All files / src/components/ui TierBadge.tsx

100% Statements 6/6
100% Branches 7/7
100% Functions 1/1
100% Lines 6/6

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58      5x                             5x                                   5x   45x     45x                         5x      
import { cva, type VariantProps } from "class-variance-authority";
import React from "react";
 
const tierBadgeVariants = cva(
  "inline-flex items-center gap-1.5 font-semibold rounded-full text-sm px-3 py-1",
  {
    variants: {
      tier: {
        love: "bg-tier-love text-tier-love-ink",
        like: "bg-tier-like text-tier-like-ink",
        maybe: "bg-tier-maybe text-tier-maybe-ink ring-1 ring-ink-soft",
        onward: "bg-tier-onward text-tier-onward-ink ring-1 ring-ink-soft",
      },
    },
    defaultVariants: { tier: "love" },
  }
);
 
const TIER_META = {
  love: { glyph: "●", label: "Love" }, // ●
  like: { glyph: "◕", label: "Like" }, // ◕
  maybe: { glyph: "◑", label: "Maybe" }, // ◑
  onward: { glyph: "○", label: "Onward" }, // ○
} as const;
 
type Tier = keyof typeof TIER_META;
 
interface TierBadgeProps
  extends React.HTMLAttributes<HTMLSpanElement>,
    VariantProps<typeof tierBadgeVariants> {
  /** Where this item sits on the value-ramp. */
  tier: Tier;
  /** Show the text label beside the glyph. Default true. */
  showLabel?: boolean;
}
 
const TierBadge = React.forwardRef<HTMLSpanElement, TierBadgeProps>(
  ({ tier = "love", showLabel = true, className = "", ...props }, ref) => {
    const meta = TIER_META[tier as Tier];
    // Glyph-only badges carry the tier in their accessible name — a visible text
    // label would break the loved ranking's deliberately label-free surface.
    return (
      <span
        ref={ref}
        className={`${tierBadgeVariants({ tier })} ${className}`}
        {...(showLabel ? {} : { role: "img", "aria-label": meta.label })}
        {...props}
      >
        <span aria-hidden="true">{meta.glyph}</span>
        {showLabel && <span>{meta.label}</span>}
      </span>
    );
  }
);
TierBadge.displayName = "TierBadge";
 
export { TierBadge };