Skip to content

Interactive Answers

Match Field

A fit field — candidates, bots or options placed by score around a centre, grouped into sectors, with threshold rings.

2 variantsMIT

Preview

Senior product designer

148 applicants · ranked by fit

2 above 85%
Design systemsFintechConsumer appsAgency50%70%85%
Malik Kaya91%
Lena Hoffmann96%

Installation

Copies the component into components/ui and installs its dependencies and theme tokens.

pnpm dlx shadcn@latest add https://tuffui.com/r/match-field.json

Usage

Pass your own data and wire the callbacks to your agent runtime.

import { MatchField } from "@/components/ui/match-field";

export function Shortlist({ role, matches }: { role: Role; matches: Match[] }) {
  return (
    <MatchField
      title={role.title}
      subtitle={`${matches.length} applicants · ranked by fit`}
      sectors={["Design systems", "Fintech", "Consumer apps", "Agency"]}
      items={matches.map((m) => ({
        id: m.id,
        name: m.name,
        sector: m.backgroundIndex,
        score: m.fit, // 0–1 from your ranking model
      }))}
      threshold={0.85}
      onSelect={(item) => openProfile(item.id)}
    />
  );
}

Props

PropTypeDefaultDescription
sectors*string[]—Categories around the edge, clockwise from the top.
items*MatchItem[]—Placed in their sector, closer to the middle the higher they score. Items at or above the threshold get a label.
title*string—Header title.
subtitlestring—Secondary line under the title.
ringsnumber[][0.5, 0.7, 0.85]Scores drawn as dashed, labeled rings.
thresholdnumberhighest ringStrong-fit score. Its ring and the dots inside it are tinted brand.
minnumberlowest ring − 0.15Score on the outer edge. Lower scores are clamped to it.
iconIconBriefcasePhosphor icon in the middle: the role or request being matched.
onSelect(item: MatchItem) => void—Called when an item is hovered, clicked or reached with the arrow keys.
classNamestring—Extra classes for the root element.
type MatchItem = {
  id: string;
  name: string;
  initials?: string; // defaults to the first letters of the name
  sector: number;    // index into sectors
  score: number;     // 0–1, higher sits closer to the middle
  color?: string;    // avatar color, defaults to a categorical palette
};