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",
|
textOverflow: "ellipsis",
|
||||||
whiteSpace: "nowrap",
|
whiteSpace: "nowrap",
|
||||||
},
|
},
|
||||||
numeric: {
|
|
||||||
fontVariantNumeric: "tabular-nums",
|
|
||||||
},
|
|
||||||
actions: {
|
actions: {
|
||||||
display: "flex",
|
display: "flex",
|
||||||
gap: "0.75rem",
|
gap: "0.75rem",
|
||||||
@@ -186,9 +183,9 @@ export default function BlocklistsPage() {
|
|||||||
{...stylex.props(shared.focusRing)}
|
{...stylex.props(shared.focusRing)}
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
<td {...stylex.props(shared.td, styles.numeric)}>{b.domain_count}</td>
|
<td {...stylex.props(shared.td, shared.tabularNums)}>{b.domain_count}</td>
|
||||||
<td {...stylex.props(shared.td, styles.numeric)}>{b.wildcard_count}</td>
|
<td {...stylex.props(shared.td, shared.tabularNums)}>{b.wildcard_count}</td>
|
||||||
<td {...stylex.props(shared.td, styles.numeric)}>{b.skipped_regex_count}</td>
|
<td {...stylex.props(shared.td, shared.tabularNums)}>{b.skipped_regex_count}</td>
|
||||||
<td {...stylex.props(shared.td)}>
|
<td {...stylex.props(shared.td)}>
|
||||||
{b.last_updated === null ? "never" : formatTime(b.last_updated)}
|
{b.last_updated === null ? "never" : formatTime(b.last_updated)}
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
@@ -1,8 +1,49 @@
|
|||||||
|
import * as stylex from "@stylexjs/stylex";
|
||||||
import { formatMicros } from "@/lib/format";
|
import { formatMicros } from "@/lib/format";
|
||||||
import type { StatsTotals } from "@/lib/types";
|
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 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 {
|
function percentOf(part: number, total: number): string | null {
|
||||||
if (total === 0) return null;
|
if (total === 0) return null;
|
||||||
return `${((part / total) * 100).toFixed(1)}%`;
|
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 }) {
|
function Card({ label, value, detail }: { label: string; value: string; detail?: string | null }) {
|
||||||
return (
|
return (
|
||||||
<div className="rounded border border-zinc-200 bg-white px-4 py-3 dark:border-zinc-800 dark:bg-zinc-900">
|
<div {...stylex.props(styles.card)}>
|
||||||
<dt className="text-sm text-zinc-500">{label}</dt>
|
<dt {...stylex.props(styles.label)}>{label}</dt>
|
||||||
<dd>
|
<dd>
|
||||||
<span className="text-2xl font-semibold tabular-nums">{value}</span>
|
<span {...stylex.props(styles.value, shared.tabularNums)}>{value}</span>
|
||||||
{detail != null && <span className="ml-2 text-sm text-zinc-500 tabular-nums">{detail}</span>}
|
{detail != null && <span {...stylex.props(styles.detail, shared.tabularNums)}>{detail}</span>}
|
||||||
</dd>
|
</dd>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@@ -22,7 +63,7 @@ function Card({ label, value, detail }: { label: string; value: string; detail?:
|
|||||||
|
|
||||||
export default function StatCards({ stats }: { stats: StatsTotals }) {
|
export default function StatCards({ stats }: { stats: StatsTotals }) {
|
||||||
return (
|
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="Queries" value={numberFormat.format(stats.queries)} />
|
||||||
<Card
|
<Card
|
||||||
label="Blocked"
|
label="Blocked"
|
||||||
|
|||||||
@@ -43,9 +43,6 @@ const styles = stylex.create({
|
|||||||
whiteSpace: "nowrap",
|
whiteSpace: "nowrap",
|
||||||
fontWeight: 500,
|
fontWeight: 500,
|
||||||
},
|
},
|
||||||
numeric: {
|
|
||||||
fontVariantNumeric: "tabular-nums",
|
|
||||||
},
|
|
||||||
actions: {
|
actions: {
|
||||||
display: "flex",
|
display: "flex",
|
||||||
gap: "0.75rem",
|
gap: "0.75rem",
|
||||||
@@ -128,7 +125,7 @@ export default function UpstreamsPage() {
|
|||||||
{u.url}
|
{u.url}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</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)}>
|
<td {...stylex.props(shared.td)}>
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
|
|||||||
@@ -151,6 +151,10 @@ export const styles = stylex.create({
|
|||||||
color: colors.dangerText,
|
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. */
|
/** For a value the operator reads character by character: a domain, an IP, a URL. */
|
||||||
mono: {
|
mono: {
|
||||||
fontFamily: "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace",
|
fontFamily: "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace",
|
||||||
|
|||||||
Reference in New Issue
Block a user