feat: add radar legend

This commit is contained in:
Mathias Schopmans
2024-02-26 17:06:46 +01:00
committed by Mathias Schopmans
parent 4c0bfa1a65
commit 0d62c0d70b
7 changed files with 100 additions and 4 deletions

View File

@@ -67,12 +67,17 @@
"new": {
"color": "#f1235a",
"title": "New",
"titleShort": "N"
"titleShort": "N",
"description": "New in this version"
},
"changed": {
"color": "#40a7d1",
"title": "Changed",
"titleShort": "C"
"titleShort": "C",
"description": "Recently changed"
},
"default": {
"description": "Unchanged"
}
},
"chart": {

View File

@@ -57,6 +57,7 @@ interface RingBadgeProps extends Omit<BadgeProps, "color" | "children"> {
ring: string;
release?: string;
}
export function RingBadge({
ring: ringName,
release,
@@ -76,14 +77,25 @@ export function RingBadge({
);
}
// Type guard to check if flag has the required attributes
function hasRequiredFlagAttributes(flag: any): flag is {
color: string;
title: string;
titleShort: string;
} {
return "color" in flag && "title" in flag && "titleShort" in flag;
}
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);
if (!flag || !hasRequiredFlagAttributes(flag)) return null;
return (
<Badge color={flag.color} size="small" {...props}>

View File

@@ -0,0 +1,35 @@
.legend {
list-style: none;
padding: 0;
margin: 0;
font-size: 14px;
display: none;
}
.icon {
display: inline-block;
vertical-align: middle;
width: 16px;
height: 16px;
margin: -2px 8px 0 0;
}
@media (min-width: 768px) {
.legend {
display: block;
position: absolute;
left: 50%;
bottom: 50px;
transform: translateX(-50%);
}
}
@media (min-width: 1200px) {
.legend {
bottom: auto;
left: auto;
right: 0;
top: 50%;
transform: translateY(-50%);
}
}

View File

@@ -0,0 +1,37 @@
import { ComponentPropsWithoutRef } from "react";
import styles from "./Legend.module.css";
import BlipChanged from "@/components/Icons/BlipChanged";
import BlipDefault from "@/components/Icons/BlipDefault";
import BlipNew from "@/components/Icons/BlipNew";
import { getFlags } from "@/lib/data";
import { Flag } from "@/lib/types";
function Icon({
flag,
...props
}: { flag: Flag } & ComponentPropsWithoutRef<"svg">) {
console.log("render Icon", flag);
switch (flag) {
case Flag.New:
return <BlipNew {...props} />;
case Flag.Changed:
return <BlipChanged {...props} />;
case Flag.Default:
return <BlipDefault {...props} />;
}
}
export function Legend() {
return (
<ul className={styles.legend}>
{Object.entries(getFlags()).map(([key, flag]) => (
<li key={key}>
<Icon flag={key as Flag} className={styles.icon} />
<span className={styles.label}>{flag.description}</span>
</li>
))}
</ul>
);
}

View File

@@ -2,6 +2,7 @@
padding: 0 15px;
margin-bottom: 60px;
position: relative;
transition: padding 200ms ease-in-out;
}
.chart {
@@ -67,7 +68,7 @@
}
}
@media (min-width: 768px) and (max-width: 1023px) {
@media (min-width: 768px) and (max-width: 1200px) {
.radar {
padding: 150px 15px;
}

View File

@@ -11,6 +11,7 @@ import styles from "./Radar.module.css";
import { Chart } from "@/components/Radar/Chart";
import { Label } from "@/components/Radar/Label";
import { Legend } from "@/components/Radar/Legend";
import { Item, Quadrant, Ring } from "@/lib/types";
import { cn } from "@/lib/utils";
@@ -96,6 +97,7 @@ export const Radar: FC<RadarProps> = ({
<Label key={quadrant.id} quadrant={quadrant} />
))}
</div>
<Legend />
<span
className={cn(styles.tooltip, tooltip.show && styles.isShown)}
style={tooltipStyle}

View File

@@ -16,7 +16,11 @@ export function getChartConfig() {
return config.chart;
}
export function getFlag(flag: Exclude<Flag, Flag.Default>) {
export function getFlags() {
return config.flags;
}
export function getFlag(flag: Flag) {
return config.flags[flag];
}