feat: add badges

This commit is contained in:
Mathias Schopmans
2024-02-15 09:55:34 +01:00
committed by Mathias Schopmans
parent 29afa82553
commit f910c9e1e5
3 changed files with 125 additions and 1 deletions

View File

@@ -0,0 +1,28 @@
.badge {
position: relative;
display: inline-block;
vertical-align: middle;
padding: 6px 15px;
text-transform: uppercase;
border: 1px solid transparent;
border-radius: 13px;
font-size: 12px;
overflow: hidden;
text-decoration: none;
}
.size-small {
padding: 4px 8px;
font-size: 9px;
}
.size-large {
padding: 7px 20px;
font-size: 14px;
border-radius: 15px;
}
.colored {
color: var(--foreground);
background-color: var(--badge);
}

View File

@@ -0,0 +1,84 @@
import {
CSSProperties,
ComponentPropsWithoutRef,
ReactNode,
useMemo,
} from "react";
import styles from "./Badge.module.css";
import { getFlag, getRing } from "@/lib/data";
import { formatRelease } from "@/lib/format";
import { Flag } from "@/lib/types";
import { cn } from "@/lib/utils";
interface BadgeProps extends ComponentPropsWithoutRef<"span"> {
children?: ReactNode;
color?: string;
size?: "small" | "medium" | "large";
}
export function Badge({
children,
color,
size = "medium",
...props
}: BadgeProps) {
const style = useMemo(
() => (color ? ({ "--badge": color } as CSSProperties) : undefined),
[color],
);
return (
<button
{...props}
style={style}
className={cn(
props.className,
styles.badge,
styles[`size-${size}`],
color && styles.colored,
)}
>
{children}
</button>
);
}
interface RingBadgeProps extends Omit<BadgeProps, "color" | "children"> {
ring: string;
release?: string;
}
export function RingBadge({
ring: ringName,
release,
...props
}: RingBadgeProps) {
const ring = getRing(ringName);
if (!ring) return null;
const label = release
? `${ring.title} | ${formatRelease(release)}`
: ring.title;
return (
<Badge color={ring.color} {...props}>
{label}
</Badge>
);
}
interface FlagBadgeProps
extends Omit<BadgeProps, "color" | "children" | "size"> {
flag: Flag;
short?: boolean;
}
export function FlagBadge({ flag: flagName, short, ...props }: FlagBadgeProps) {
if (flagName === Flag.Default) return null;
const flag = getFlag(flagName);
return (
<Badge color={flag.color} size="small" {...props}>
{short ? flag.titleShort : flag.title}
</Badge>
);
}