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.jsonUsage
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
| Prop | Type | Default | Description |
|---|---|---|---|
| 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. |
| subtitle | string | — | Secondary line under the title. |
| rings | number[] | [0.5, 0.7, 0.85] | Scores drawn as dashed, labeled rings. |
| threshold | number | highest ring | Strong-fit score. Its ring and the dots inside it are tinted brand. |
| min | number | lowest ring − 0.15 | Score on the outer edge. Lower scores are clamped to it. |
| icon | Icon | Briefcase | Phosphor 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. |
| className | string | — | 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
};