From f910c9e1e5f68e0630a39c6f671697153a49c99a Mon Sep 17 00:00:00 2001 From: Mathias Schopmans Date: Thu, 15 Feb 2024 09:55:34 +0100 Subject: [PATCH] feat: add badges --- data/config.json | 14 ++++- src/components/Badge/Badge.module.css | 28 +++++++++ src/components/Badge/Badge.tsx | 84 +++++++++++++++++++++++++++ 3 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 src/components/Badge/Badge.module.css create mode 100644 src/components/Badge/Badge.tsx diff --git a/data/config.json b/data/config.json index bbee01f..fee8722 100644 --- a/data/config.json +++ b/data/config.json @@ -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" + } + } } diff --git a/src/components/Badge/Badge.module.css b/src/components/Badge/Badge.module.css new file mode 100644 index 0000000..3ef0dfe --- /dev/null +++ b/src/components/Badge/Badge.module.css @@ -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); +} diff --git a/src/components/Badge/Badge.tsx b/src/components/Badge/Badge.tsx new file mode 100644 index 0000000..5cdb260 --- /dev/null +++ b/src/components/Badge/Badge.tsx @@ -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 ( + + ); +} + +interface RingBadgeProps extends Omit { + 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 ( + + {label} + + ); +} + +interface FlagBadgeProps + extends Omit { + flag: Flag; + short?: boolean; +} +export function FlagBadge({ flag: flagName, short, ...props }: FlagBadgeProps) { + if (flagName === Flag.Default) return null; + const flag = getFlag(flagName); + + return ( + + {short ? flag.titleShort : flag.title} + + ); +}