fix: remove @emotion/react from <LastSeen /> (#27199)

This removes the manual `@emotion/react` we had from the theme being
injected in `<LastSeen />`. This now is relying on Tailwind 🙂
This commit is contained in:
Jake Howell
2026-07-13 18:05:32 +00:00
committed by GitHub
parent ad29777cb2
commit aee528e044
+30 -28
View File
@@ -1,48 +1,50 @@
import { useTheme } from "@emotion/react";
import dayjs from "dayjs";
import type dayjs from "dayjs";
import type { FC, HTMLAttributes } from "react";
import { cn } from "#/utils/cn";
import { isAfter, relativeTime, subtractTime } from "#/utils/time";
import { isAfter, subtractTime, timeFrom } from "#/utils/time";
interface LastSeenProps
extends Omit<HTMLAttributes<HTMLSpanElement>, "children"> {
at: dayjs.ConfigType;
// Injectable reference time so the component is deterministic in tests.
now?: dayjs.ConfigType;
"data-pixel"?: string; // prevents a type error in the stories
}
export const LastSeen: FC<LastSeenProps> = ({ at, className, ...attrs }) => {
const theme = useTheme();
const _t = dayjs(at);
const now = new Date();
const oneHourAgo = subtractTime(now, 1, "hour");
const threeDaysAgo = subtractTime(now, 3, "day");
const oneMonthAgo = subtractTime(now, 1, "month");
const centuryAgo = subtractTime(now, 100, "year");
let message = relativeTime(at);
let color = theme.palette.text.secondary;
if (isAfter(at, oneHourAgo)) {
const displayFor = (
at: dayjs.ConfigType,
now: dayjs.ConfigType,
): { message: string; color: string } => {
if (isAfter(at, subtractTime(now, 1, "hour"))) {
// Since the agent reports on a 10m interval,
// the last_used_at can be inaccurate when recent.
message = "Now";
color = theme.roles.success.fill.solid;
} else if (isAfter(at, threeDaysAgo)) {
color = theme.experimental.l2.text;
} else if (isAfter(at, oneMonthAgo)) {
color = theme.roles.warning.fill.solid;
} else if (isAfter(at, centuryAgo)) {
color = theme.roles.error.fill.solid;
} else {
message = "Never";
return { message: "Now", color: "text-content-success" };
}
if (isAfter(at, subtractTime(now, 3, "day"))) {
return { message: timeFrom(at, now), color: "text-content-primary" };
}
if (isAfter(at, subtractTime(now, 1, "month"))) {
return { message: timeFrom(at, now), color: "text-content-warning" };
}
if (isAfter(at, subtractTime(now, 100, "year"))) {
return { message: timeFrom(at, now), color: "text-content-destructive" };
}
return { message: "Never", color: "text-content-secondary" };
};
export const LastSeen: FC<LastSeenProps> = ({
at,
now = new Date(),
className,
...attrs
}) => {
const { message, color } = displayFor(at, now);
return (
<span
data-pixel="ignore"
style={{ color }}
{...attrs}
className={cn(["whitespace-nowrap", className])}
className={cn(["whitespace-nowrap", color, className])}
>
{message}
</span>