Touchstone
Feature comparison matrix in two modes — plans (3–4 pricing columns) or versus (your product framed in the accent against alternatives). Collapsible row groups, a sticky name/price/CTA header that frosts once pinned, checks that draw in row by row, row hover with floating hints, column-header dimming, and a one-column view with a segmented picker and swipe under 640px. Real table semantics.
The preview is live. The source is Pro.
One purchase, lifetime access: every pro component's source, CLI install with your own registry token, and all future drops.
Installation
CLI
npx shadcn@latest add @crucible/touchstoneManual — install dependencies, then copy the source
npm install motionProps
| Prop | Type | Default | Description |
|---|---|---|---|
| mode | "plans" | "versus" | "plans" | "plans" compares 3–4 pricing plans; "versus" compares your product (the highlighted column) against 2–3 alternatives. Also picks the sample data when columns/groups are omitted. |
| columns | TouchstoneColumn[] | Column definitions. Omit for sample data matching mode. | |
| groups | TouchstoneGroup[] | Grouped feature rows. Omit for sample data matching mode. | |
| eyebrow | React.ReactNode | Small label above the title. Pass null to hide. | |
| title | React.ReactNode | Section heading. Pass null to hide the header block. | |
| subtitle | React.ReactNode | Supporting line under the title. | |
| footnote | React.ReactNode | Muted footnote beside the legend. | |
| defaultCollapsed | string[] | [] | Group labels collapsed on first render. |
| onGroupToggle | (label: string, open: boolean) => void | Fires when a group is expanded or collapsed. | |
| onColumnChange | (index: number) => void | Fires when the narrow-view column changes (picker or swipe). | |
| stickyOffset | number | 0 | Distance from the top of the scroll container where the column header pins, in px (e.g. a fixed navbar). |
| accentColor | string | "#e9c46a" | The single signature accent — highlight frame, checks in the highlighted column, primary CTA, focus rings. |
| ref | React.Ref<TouchstoneHandle> | Imperative handle (replay(), expandAll(), collapseAll(), showColumn()). React 19 ref-as-prop. | |
| className | string | Extra classes for the <section> root. | |
Also accepts all props of Omit<React.ComponentPropsWithoutRef<"section">, "children" | "title"> — they pass through to the underlying element. | |||
Honors prefers-reduced-motion with a designed static fallback, and passes className through.