Back
Standalone v1.10.3 Star on GitHub

vois-components

Resolves which component to use when two similar options both seem right.

Vois Components picks the exact component for the job when two similar options both look right: Dialog or Drawer, Toast or Banner, Select or Combobox. It runs after vois-patterns sets the structure and before vois-tokens applies the styling, and it logs every choice so the same decision doesn't get re-argued next time.

  • Job-to-be-done

    Describe what the component needs to accomplish as a verb plus object: confirm a destructive action, show transient feedback, group related controls.

  • Component selection

    The specific component name from the Vois manifest with alternatives considered and one-sentence reasoning for why this one wins.

  • record_component_choice log

    A structured log entry for every selection made, feeding the self-improving design system.

Load the vois-components skill. I need to [describe the job-to-be-done, e.g. confirm a destructive action / show transient feedback].

Skills that call into or pair with this one. Click a node to open it. Expand the reference files node to browse them on GitHub.

Static previews from the Claude Design edition of this skill. Free to browse, no install required.

Get this skill

Download the SKILL.md file and install it in Claude or Cursor.

  1. Download the SKILL.md file using the button above.
  2. Open claude.ai and go to Settings.
  3. Select Skills from the sidebar.
  4. Click Add skill and upload the SKILL.md file.
  5. Give the skill a name and save. Claude loads it automatically when relevant.

Skills installed in Claude persist across conversations. Claude reads the skill when the trigger conditions match your message.

Vois Component Selection Skill

You are picking specific components from the workspace manifest. This skill answers “which component for this job” — not what structure (that’s vois-patterns) and not how to style it (that’s vois-tokens).

Read this skill after vois-patterns has determined the container type. If a vois_record_component_choice tool is available in your environment, call it for every component you pick before moving to vois-tokens; if not, just make the selection and move on.

The Quick Reference table below resolves most cases on its own. When it doesn’t — ambiguous case, need the full decision tree, or need to justify the choice — read the matching reference file.


Before You Pick a Component

  1. Identify the job-to-be-done — phrase it as a verb plus object: “confirm a destructive action”, “show transient feedback”, “group related controls”

  2. Find the matching row in Quick Reference, or the matching job in the index below

  3. If ambiguous, read the matching reference file and walk its decision tree

  4. If a vois_record_component_choice tool is available, call it with your selection:

    Tool: vois_record_component_choice
    Arguments:
      job: <the job-to-be-done, one sentence, e.g. "confirm destructive action">
      componentName: <exact component name from the manifest, e.g. "AlertDialog">
      alternativesConsidered: <optional array of component names you ruled out>
      reasoning: <optional one sentence on why you chose this over the alternatives>

    If that tool isn’t available, this step is optional telemetry — proceed with your selection.

  5. If no section matches your job and a vois_report_pattern_gap tool is available, call it:

    Tool: vois_report_pattern_gap
    Arguments:
      skillVersion: <this skill's version, from SKILL.md frontmatter>
      userGoal: <what the UI needs to do>
      attemptedFallback: <closest job ID from this skill, e.g. JOB-OVERLAY-INTERACTION>
      reasoning: <what the rubrics don't cover>

    There is no description/closestPathId/gapDescription argument shape on the real tool — use the fields above. If the tool isn’t available, just note the gap in your own output and proceed with the closest match.

Note on workspace manifests. These rubrics use standard shadcn/ui component names. Your workspace may extend or rename them — e.g. Banner instead of Alert, DataTable instead of Table. Check your workspace manifest for the exact name; use the rubric logic to make the selection, then record the workspace-specific name.


Quick Reference

JobUseNot
Confirm destructive actionAlertDialogDialog, Toast
Fixed-length one-time codeInputOTPInput
Transient feedback, no action neededToastAlert, Banner
Transient feedback, action requiredAlert (persistent)Toast
Focused overlay, exactly one field anchored to a row/itemPopoverSheet, Dialog
Focused overlay, short taskDialogDrawer, Sheet
Focused overlay, a handful of fields or more, contextual to a list itemSheetDialog, Popover
Group content, interactive itemCarddiv, Surface
Switch between major content areasTabsSegmented Control
Filter a list, 2–4 optionsSegmented ControlTabs
Choose from short listSelectCombobox
Choose from long list / searchComboboxSelect
Search + trigger actionsCommandSelect, Combobox
Short label, no interactionTooltipPopover
Rich content, triggered by clickPopoverTooltip
Immediate-effect binary settingSwitchCheckbox
Form field binary / consentCheckboxSwitch
Page load or content fetchSkeletonSpinner
Action in progressSpinner (inline)Skeleton
Measurable long operationProgressSpinner
True zero stateEmptyState with CTABlank space
Filtered to zero resultsInline message + clearEmptyState
Row-level actionsDropdownMenuContextMenu, Command
Right-click enhancementContextMenuDropdownMenu
2–5 sequential required steps, each fits a page containerStepper (references/stepper.md)Progress, Tabs, Wizard
6+ steps, or a step that needs its own full pageWizardStepper
3+ levels deep, counting HomeBreadcrumbBack link
2 levels deep, counting HomeBack linkBreadcrumb
Simple collection, no sortingListTable
Comparable attributes, < 100 rowsTableDataTable
One headline numberStat tile in a Card (see vois-dataviz)A one-bar chart
Trend, comparison, share, distributionChart: walk the vois-dataviz decision treeA table of raw rows
100+ rows, sortable, bulk actionsDataTableTable
Open a record from a table rowSheet (full page if the record is big)Dialog
Table first loadSkeleton rows under real headersSpinner
Persistent app navigationSidebarDrawer
Contextual tools for selected itemSheet or PanelSidebar, Drawer

Lookalikes: Don’t Hand-Build These

Agents often write markup that looks like a component but isn’t one. A screen can follow every rule in this skill and still contain one. Before you write markup for any of these, use the component. The full rows (why, rule IDs, evidence, a signal a script can match) are in data/components-rules.json under lookalikes.

Seen in blind builds (vois-eval/lookalike-pass, 40 builds):

If you are about to writeUse instead
A raw <button> with your own focus ring, as a text link, an icon in an input, or a Tooltip or Popover triggerButton: variant="link" for text, variant="ghost" with an icon size and aria-label for icons, asChild as a trigger
Loader2 with animate-spinSpinner
Buttons with role="radio"RadioGroup, or ToggleGroup (single) for a segmented control
Numbered circles joined by linesThe shared Stepper (references/stepper.md)

Not seen, but already forbidden by a rule:

If you are about to writeUse instead
div or span with onClickButton, or a link for navigation
fixed inset-0 backdrop and a centered boxDialog, AlertDialog or Sheet
setTimeout that hides a messageSonner toast
”x” or ”×” text as a closeThe Dialog or Sheet close, or a ghost icon Button with aria-label
window.confirm, alert or promptAlertDialog, or Sonner
A colored border-l-4 box with an icon and textAlert with a status role
title="..." as a tooltipTooltip

When the prompt describes how something looks (“a red × in the corner”, “a pill with a circle”), pick the component by its job, then style it. The look in a prompt is not the component.

Job Index

data/components-rules.json has the full decision tree (condition → recommended component, including nested thresholds and edge cases) plus every “why not X” rationale, for all 21 jobs — query it by id or number. This is now the only source for this content; the prose reference files it was extracted from have been removed as fully redundant.

Component specs: when a pick has no shadcn component and agents hand-build it, the spec lives in references/. Today that is references/stepper.md (the Stepper that JOB-MULTISTEP-GUIDE picks).

Source of truth: data/components-rules.json is canonical and, since the prose reference files were removed, the only source for decision-tree content. The Job Index table above is the one place each JOB-* ID is tagged in prose, and each JSON entry’s source_file points here.

Job IDJob
JOB-CONFIRM-DESTRUCTIVEJob 1 Confirm destructive action
JOB-TRANSIENT-FEEDBACKJob 2 Transient feedback
JOB-OVERLAY-INTERACTIONJob 3 Focused overlay interaction
JOB-CONTAIN-CONTENTJob 4 Contain a unit of content
JOB-SWITCH-VIEWSJob 5 Switch views / filter
JOB-CHOOSE-FROM-LISTJob 6 Choose from a list
JOB-CONTEXTUAL-INFOJob 7 Contextual info (tooltip/popover)
JOB-TRIGGER-ACTIONJob 8 Trigger an action
JOB-ACCEPT-TEXTJob 9 Accept text input
JOB-BINARY-PREFERENCEJob 10 Binary preference
JOB-LABEL-CONTENTJob 11 Label/categorize content
JOB-REPRESENT-USERJob 12 Represent a user/group
JOB-LOADING-STATEJob 13 Loading state
JOB-EMPTY-CONTENTJob 14 Empty content
JOB-EXPOSE-ACTIONSJob 15 Expose a set of actions
JOB-MULTISTEP-GUIDEJob 16 Multi-step process
JOB-NAVIGATION-POSITIONJob 17 Position in a hierarchy
JOB-DISPLAY-DATAJob 18 Display structured data
JOB-DATA-ENTRYJob 19 Data entry surface
JOB-SECONDARY-CONTENTJob 20 Secondary content / persistent nav
JOB-VISUALIZE-DATAJob 21 Visualize data (hands the form choice to vois-dataviz)

Relationship to Other Skills

Read vois-patterns first. That skill determines the container type — settings page, form, table, dialog. Once you know the structure, come here to pick the specific components that fill it.

vois-dataviz for charts. JOB-VISUALIZE-DATA picks the container (Card, Tabs, filter row, states). The chart form, chart colors, honesty rules and dashboard structure come from vois-dataviz.

Read vois-tokens after. Once components are selected, vois-tokens handles tokens, spacing, animation, and accessibility implementation.

Righter for all copy. Component labels, empty state messages, button text, error copy — all of it goes through righter (which calls vois_get_microcopy first). This skill says nothing about words.