1---
2import { Check, Lightbulb, Clock, type Icon as IconType } from "@lucide/astro";
3
4const statusStrings = {
5 planned: "Planned",
6 "in-progress": "In Progress",
7 complete: "Complete",
8} as const;
9
10interface Props {
11 title: string;
12 icon: typeof IconType;
13 status?: "planned" | "in-progress" | "complete";
14}
15
16const { title, icon: Icon, status = "planned" } = Astro.props;
17let StatusIcon: typeof IconType;
18
19switch (status) {
20 case "planned":
21 StatusIcon = Lightbulb;
22 break;
23 case "in-progress":
24 StatusIcon = Clock;
25 break;
26 case "complete":
27 StatusIcon = Check;
28 break;
29}
30---
31
32<li class="roadmap-item">
33 <div
34 class="icon flex size-10 items-center justify-center rounded-lg border-2 border-black/20 bg-black/50"
35 >
36 <Icon aria-hidden="true" />
37 </div>
38
39 <article class="flex flex-col items-start gap-0.5">
40 <p
41 class="flex items-center gap-1 rounded-full border-2 border-black/20 px-2 py-0.5 text-xs tracking-wide uppercase"
42 class:list={{
43 "bg-black/50": status === "planned",
44 "bg-purple-950/70": status === "in-progress",
45 "bg-emerald-950/70": status === "complete",
46 }}
47 >
48 <StatusIcon size={12} aria-hidden="true" />
49 {statusStrings[status]}
50 </p>
51 <h3 class="text-lg font-semibold">{title}</h3>
52 <slot />
53 </article>
54
55 <hr aria-hidden="true" />
56 <hr aria-hidden="true" />
57</li>
58
59<style>
60 @reference "../style/main.css";
61
62 .roadmap-item {
63 display: grid;
64 grid-template-columns: 40px 1fr;
65 grid-template-rows: 2rem 40px auto;
66 grid-template-areas:
67 "top-vr blank"
68 "icon content"
69 "bottom-vr content";
70
71 & > div {
72 grid-area: icon;
73 }
74
75 & > article {
76 grid-area: content;
77 padding-left: 2rem;
78 }
79
80 & > hr {
81 @apply bg-black/60;
82 width: 0.25rem;
83 height: 100%;
84 border: none;
85 margin: 0 auto;
86
87 &:first-of-type {
88 grid-area: top-vr;
89 }
90
91 &:last-of-type {
92 grid-area: bottom-vr;
93 }
94 }
95
96 &:first-child > hr:first-of-type {
97 display: none;
98 }
99
100 &:last-child > hr:last-of-type {
101 display: none;
102 }
103 }
104</style>