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

@@ -54,5 +54,17 @@
"description": "This category is a bit special. Unlike the others, we recommend to stop doing or using something. That does not mean that they are bad and it often might be ok to use them in existing projects. But we move things here if we think we shouldn't do them anymore - because we see better options or alternatives now.", "description": "This category is a bit special. Unlike the others, we recommend to stop doing or using something. That does not mean that they are bad and it often might be ok to use them in existing projects. But we move things here if we think we shouldn't do them anymore - because we see better options or alternatives now.",
"color": "#688190" "color": "#688190"
} }
] ],
"flags": {
"new": {
"color": "#f1235a",
"title": "New",
"titleShort": "N"
},
"changed": {
"color": "#40a7d1",
"title": "Changed",
"titleShort": "C"
}
}
} }

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>
);
}