mirror of
https://github.com/Xevion/rdap.git
synced 2025-12-06 01:16:00 -06:00
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:
@@ -3,7 +3,7 @@ import { useMemo } from "react";
|
|||||||
import { format } from "date-fns";
|
import { format } from "date-fns";
|
||||||
import { formatInTimeZone } from "date-fns-tz";
|
import { formatInTimeZone } from "date-fns-tz";
|
||||||
import TimeAgo from "react-timeago";
|
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";
|
import { useDateFormat } from "@/contexts/DateFormatContext";
|
||||||
|
|
||||||
type DynamicDateProps = {
|
type DynamicDateProps = {
|
||||||
@@ -65,9 +65,17 @@ const DynamicDate: FunctionComponent<DynamicDateProps> = ({
|
|||||||
</Box>
|
</Box>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Button variant="ghost" size="1" onClick={toggleFormat} style={{ cursor: "pointer" }}>
|
<time
|
||||||
<Text size="2">{displayValue}</Text>
|
dateTime={isoString}
|
||||||
</Button>
|
onClick={toggleFormat}
|
||||||
|
style={{
|
||||||
|
cursor: "pointer",
|
||||||
|
textDecoration: "none",
|
||||||
|
fontSize: "var(--font-size-2)",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{displayValue}
|
||||||
|
</time>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
21
src/components/EmDash.tsx
Normal file
21
src/components/EmDash.tsx
Normal 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",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
—
|
||||||
|
</Text>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default EmDash;
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import type { FunctionComponent } from "react";
|
import type { FunctionComponent } from "react";
|
||||||
import type { Event } from "@/rdap/schemas";
|
import type { Event } from "@/rdap/schemas";
|
||||||
import DynamicDate from "@/components/DynamicDate";
|
import DynamicDate from "@/components/DynamicDate";
|
||||||
|
import EmDash from "@/components/EmDash";
|
||||||
import { Table, Text } from "@radix-ui/themes";
|
import { Table, Text } from "@radix-ui/themes";
|
||||||
|
|
||||||
export type EventsProps = {
|
export type EventsProps = {
|
||||||
@@ -32,9 +33,7 @@ const Events: FunctionComponent<EventsProps> = ({ data }) => {
|
|||||||
{eventActor}
|
{eventActor}
|
||||||
</Text>
|
</Text>
|
||||||
) : (
|
) : (
|
||||||
<Text size="2" style={{ color: "var(--gray-a4)" }}>
|
<EmDash />
|
||||||
—
|
|
||||||
</Text>
|
|
||||||
)}
|
)}
|
||||||
</Table.Cell>
|
</Table.Cell>
|
||||||
</Table.Row>
|
</Table.Row>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import type { FunctionComponent } from "react";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import type { Link as RdapLink } from "@/rdap/schemas";
|
import type { Link as RdapLink } from "@/rdap/schemas";
|
||||||
import { Table, Link, Text, Badge } from "@radix-ui/themes";
|
import { Table, Link, Text, Badge } from "@radix-ui/themes";
|
||||||
|
import EmDash from "@/components/EmDash";
|
||||||
|
|
||||||
export type LinksSectionProps = {
|
export type LinksSectionProps = {
|
||||||
links: RdapLink[];
|
links: RdapLink[];
|
||||||
@@ -28,35 +29,25 @@ const LinksSection: FunctionComponent<LinksSectionProps> = ({ links }) => {
|
|||||||
{link.href}
|
{link.href}
|
||||||
</Link>
|
</Link>
|
||||||
</Table.Cell>
|
</Table.Cell>
|
||||||
<Table.Cell>
|
<Table.Cell align="center">
|
||||||
{link.rel ? (
|
{link.rel ? (
|
||||||
<Badge variant="soft" size="1">
|
<Badge variant="soft" size="1">
|
||||||
{link.rel}
|
{link.rel}
|
||||||
</Badge>
|
</Badge>
|
||||||
) : (
|
) : (
|
||||||
<Text size="2" style={{ color: "var(--gray-a6)" }}>
|
<EmDash />
|
||||||
—
|
|
||||||
</Text>
|
|
||||||
)}
|
)}
|
||||||
</Table.Cell>
|
</Table.Cell>
|
||||||
<Table.Cell>
|
<Table.Cell align="center">
|
||||||
{link.title ? (
|
{link.title ? <Text size="2">{link.title}</Text> : <EmDash />}
|
||||||
<Text size="2">{link.title}</Text>
|
|
||||||
) : (
|
|
||||||
<Text size="2" style={{ color: "var(--gray-a6)" }}>
|
|
||||||
—
|
|
||||||
</Text>
|
|
||||||
)}
|
|
||||||
</Table.Cell>
|
</Table.Cell>
|
||||||
<Table.Cell>
|
<Table.Cell align="right">
|
||||||
{link.type ? (
|
{link.type ? (
|
||||||
<Text size="2" color="gray">
|
<Text size="2" color="gray">
|
||||||
{link.type}
|
{link.type}
|
||||||
</Text>
|
</Text>
|
||||||
) : (
|
) : (
|
||||||
<Text size="2" style={{ color: "var(--gray-a6)" }}>
|
<EmDash />
|
||||||
—
|
|
||||||
</Text>
|
|
||||||
)}
|
)}
|
||||||
</Table.Cell>
|
</Table.Cell>
|
||||||
</Table.Row>
|
</Table.Row>
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import type { FunctionComponent } from "react";
|
import type { FunctionComponent } from "react";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import type { Nameserver } from "@/rdap/schemas";
|
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 CopyButton from "@/components/CopyButton";
|
||||||
|
import EmDash from "@/components/EmDash";
|
||||||
|
|
||||||
export type NameserversSectionProps = {
|
export type NameserversSectionProps = {
|
||||||
nameservers: Nameserver[];
|
nameservers: Nameserver[];
|
||||||
@@ -39,7 +40,7 @@ const NameserversSection: FunctionComponent<NameserversSectionProps> = ({ namese
|
|||||||
</Flex>
|
</Flex>
|
||||||
)}
|
)}
|
||||||
</Table.Cell>
|
</Table.Cell>
|
||||||
<Table.Cell>
|
<Table.Cell align="center">
|
||||||
{ns.ipAddresses?.v4 && ns.ipAddresses.v4.length > 0 ? (
|
{ns.ipAddresses?.v4 && ns.ipAddresses.v4.length > 0 ? (
|
||||||
<Flex direction="column" gap="1">
|
<Flex direction="column" gap="1">
|
||||||
{ns.ipAddresses.v4.map((ip, ipIndex) => (
|
{ns.ipAddresses.v4.map((ip, ipIndex) => (
|
||||||
@@ -52,12 +53,10 @@ const NameserversSection: FunctionComponent<NameserversSectionProps> = ({ namese
|
|||||||
))}
|
))}
|
||||||
</Flex>
|
</Flex>
|
||||||
) : (
|
) : (
|
||||||
<Text size="2" style={{ color: "var(--gray-a4)" }}>
|
<EmDash />
|
||||||
—
|
|
||||||
</Text>
|
|
||||||
)}
|
)}
|
||||||
</Table.Cell>
|
</Table.Cell>
|
||||||
<Table.Cell>
|
<Table.Cell align="right">
|
||||||
{ns.ipAddresses?.v6 && ns.ipAddresses.v6.length > 0 ? (
|
{ns.ipAddresses?.v6 && ns.ipAddresses.v6.length > 0 ? (
|
||||||
<Flex direction="column" gap="1">
|
<Flex direction="column" gap="1">
|
||||||
{ns.ipAddresses.v6.map((ip, ipIndex) => (
|
{ns.ipAddresses.v6.map((ip, ipIndex) => (
|
||||||
@@ -70,9 +69,7 @@ const NameserversSection: FunctionComponent<NameserversSectionProps> = ({ namese
|
|||||||
))}
|
))}
|
||||||
</Flex>
|
</Flex>
|
||||||
) : (
|
) : (
|
||||||
<Text size="2" style={{ color: "var(--gray-a4)" }}>
|
<EmDash />
|
||||||
—
|
|
||||||
</Text>
|
|
||||||
)}
|
)}
|
||||||
</Table.Cell>
|
</Table.Cell>
|
||||||
</Table.Row>
|
</Table.Row>
|
||||||
|
|||||||
@@ -26,7 +26,9 @@ const RemarksSection: FunctionComponent<RemarksSectionProps> = ({ remarks }) =>
|
|||||||
<Flex direction="column" gap="2">
|
<Flex direction="column" gap="2">
|
||||||
{remark.title && (
|
{remark.title && (
|
||||||
<Flex align="center" gap="2">
|
<Flex align="center" gap="2">
|
||||||
<Heading size="3">{remark.title}</Heading>
|
<Heading size="3" weight="medium">
|
||||||
|
{remark.title}
|
||||||
|
</Heading>
|
||||||
{remark.type && (
|
{remark.type && (
|
||||||
<Badge variant="soft" size="1">
|
<Badge variant="soft" size="1">
|
||||||
{remark.type}
|
{remark.type}
|
||||||
|
|||||||
Reference in New Issue
Block a user