feat: add badges
This commit is contained in:
committed by
Mathias Schopmans
parent
29afa82553
commit
f910c9e1e5
@@ -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.",
|
||||
"color": "#688190"
|
||||
}
|
||||
]
|
||||
],
|
||||
"flags": {
|
||||
"new": {
|
||||
"color": "#f1235a",
|
||||
"title": "New",
|
||||
"titleShort": "N"
|
||||
},
|
||||
"changed": {
|
||||
"color": "#40a7d1",
|
||||
"title": "Changed",
|
||||
"titleShort": "C"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
28
src/components/Badge/Badge.module.css
Normal file
28
src/components/Badge/Badge.module.css
Normal 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);
|
||||
}
|
||||
84
src/components/Badge/Badge.tsx
Normal file
84
src/components/Badge/Badge.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user