This repository has no description
1<script module lang="ts">
2 import { tv, type VariantProps } from "tailwind-variants";
3
4 export const issueStatePill = tv({
5 base: "inline-flex items-center gap-1 rounded-sm px-2 py-1 typography-paragraph-small text-foreground-on-emphasis select-none",
6 variants: {
7 state: {
8 open: "bg-background-success-emphasis",
9 closed: "bg-background-neutral-emphasis"
10 }
11 },
12 defaultVariants: {
13 state: "open"
14 }
15 });
16
17 export type IssueStatePillVariants = VariantProps<typeof issueStatePill>;
18</script>
19
20<script lang="ts">
21 import CircleDot from "$icon/circle-dot";
22 import Ban from "$icon/ban";
23
24 interface Props {
25 state: IssueStatePillVariants["state"];
26 class?: string;
27 }
28
29 let { state = "open", class: className }: Props = $props();
30
31 const Icon = $derived(state === "closed" ? Ban : CircleDot);
32 const label = $derived(state === "closed" ? "Closed" : "Open");
33</script>
34
35<span class={issueStatePill({ state, class: className })}>
36 <Icon class="size-3 shrink-0" aria-hidden="true" />
37 <!--
38 Inter's ascent/descent split isn't symmetric in the line box, so a mathematically
39 centred label reads high. nudge the text alone (a transform, so the icon and the
40 pill's height are untouched) to land it on the optical centre.
41 -->
42 <span>{label}</span>
43</span>