refactor: introduce EmDash component and improve table semantics

Created a reusable EmDash component to standardize placeholder rendering
across tables. Updated DynamicDate to use semantic <time> element instead
of Button wrapper. Improved table alignment with proper left/center/right
positioning in LinksSection and NameserversSection. Enhanced typography in
RemarksSection with medium font weight for headings.
This commit is contained in:
2025-10-23 15:14:57 -05:00
parent 704b8380f6
commit 2c67f49e2f
6 changed files with 51 additions and 33 deletions

View File

@@ -3,7 +3,7 @@ import { useMemo } from "react";
import { format } from "date-fns";
import { formatInTimeZone } from "date-fns-tz";
import TimeAgo from "react-timeago";
import { Box, Button, Tooltip, Text, Flex } from "@radix-ui/themes";
import { Box, Tooltip, Text, Flex } from "@radix-ui/themes";
import { useDateFormat } from "@/contexts/DateFormatContext";
type DynamicDateProps = {
@@ -65,9 +65,17 @@ const DynamicDate: FunctionComponent<DynamicDateProps> = ({
</Box>
}
>
<Button variant="ghost" size="1" onClick={toggleFormat} style={{ cursor: "pointer" }}>
<Text size="2">{displayValue}</Text>
</Button>
<time
dateTime={isoString}
onClick={toggleFormat}
style={{
cursor: "pointer",
textDecoration: "none",
fontSize: "var(--font-size-2)",
}}
>
{displayValue}
</time>
</Tooltip>
);
};

21
src/components/EmDash.tsx Normal file
View File

@@ -0,0 +1,21 @@
import type { FunctionComponent } from "react";
import { Text } from "@radix-ui/themes";
/**
* A reusable em dash component for displaying placeholder text in tables.
*/
const EmDash: FunctionComponent = () => {
return (
<Text
size="2"
style={{
color: "var(--gray-a8)",
userSelect: "none",
}}
>
&mdash;
</Text>
);
};
export default EmDash;

View File

@@ -1,6 +1,7 @@
import type { FunctionComponent } from "react";
import type { Event } from "@/rdap/schemas";
import DynamicDate from "@/components/DynamicDate";
import EmDash from "@/components/EmDash";
import { Table, Text } from "@radix-ui/themes";
export type EventsProps = {
@@ -32,9 +33,7 @@ const Events: FunctionComponent<EventsProps> = ({ data }) => {
{eventActor}
</Text>
) : (
<Text size="2" style={{ color: "var(--gray-a4)" }}>
</Text>
<EmDash />
)}
</Table.Cell>
</Table.Row>

View File

@@ -2,6 +2,7 @@ import type { FunctionComponent } from "react";
import React from "react";
import type { Link as RdapLink } from "@/rdap/schemas";
import { Table, Link, Text, Badge } from "@radix-ui/themes";
import EmDash from "@/components/EmDash";
export type LinksSectionProps = {
links: RdapLink[];
@@ -28,35 +29,25 @@ const LinksSection: FunctionComponent<LinksSectionProps> = ({ links }) => {
{link.href}
</Link>
</Table.Cell>
<Table.Cell>
<Table.Cell align="center">
{link.rel ? (
<Badge variant="soft" size="1">
{link.rel}
</Badge>
) : (
<Text size="2" style={{ color: "var(--gray-a6)" }}>
</Text>
<EmDash />
)}
</Table.Cell>
<Table.Cell>
{link.title ? (
<Text size="2">{link.title}</Text>
) : (
<Text size="2" style={{ color: "var(--gray-a6)" }}>
</Text>
)}
<Table.Cell align="center">
{link.title ? <Text size="2">{link.title}</Text> : <EmDash />}
</Table.Cell>
<Table.Cell>
<Table.Cell align="right">
{link.type ? (
<Text size="2" color="gray">
{link.type}
</Text>
) : (
<Text size="2" style={{ color: "var(--gray-a6)" }}>
</Text>
<EmDash />
)}
</Table.Cell>
</Table.Row>

View File

@@ -1,8 +1,9 @@
import type { FunctionComponent } from "react";
import React from "react";
import type { Nameserver } from "@/rdap/schemas";
import { Table, Text, Code, Flex, Badge } from "@radix-ui/themes";
import { Table, Code, Flex, Badge } from "@radix-ui/themes";
import CopyButton from "@/components/CopyButton";
import EmDash from "@/components/EmDash";
export type NameserversSectionProps = {
nameservers: Nameserver[];
@@ -39,7 +40,7 @@ const NameserversSection: FunctionComponent<NameserversSectionProps> = ({ namese
</Flex>
)}
</Table.Cell>
<Table.Cell>
<Table.Cell align="center">
{ns.ipAddresses?.v4 && ns.ipAddresses.v4.length > 0 ? (
<Flex direction="column" gap="1">
{ns.ipAddresses.v4.map((ip, ipIndex) => (
@@ -52,12 +53,10 @@ const NameserversSection: FunctionComponent<NameserversSectionProps> = ({ namese
))}
</Flex>
) : (
<Text size="2" style={{ color: "var(--gray-a4)" }}>
</Text>
<EmDash />
)}
</Table.Cell>
<Table.Cell>
<Table.Cell align="right">
{ns.ipAddresses?.v6 && ns.ipAddresses.v6.length > 0 ? (
<Flex direction="column" gap="1">
{ns.ipAddresses.v6.map((ip, ipIndex) => (
@@ -70,9 +69,7 @@ const NameserversSection: FunctionComponent<NameserversSectionProps> = ({ namese
))}
</Flex>
) : (
<Text size="2" style={{ color: "var(--gray-a4)" }}>
</Text>
<EmDash />
)}
</Table.Cell>
</Table.Row>

View File

@@ -26,7 +26,9 @@ const RemarksSection: FunctionComponent<RemarksSectionProps> = ({ remarks }) =>
<Flex direction="column" gap="2">
{remark.title && (
<Flex align="center" gap="2">
<Heading size="3">{remark.title}</Heading>
<Heading size="3" weight="medium">
{remark.title}
</Heading>
{remark.type && (
<Badge variant="soft" size="1">
{remark.type}