ComponentsSite blocks

Comparison table

A plan × feature detail table, or a two-column “us vs. them”. A real <table> with a caption, scoped row and column headers, grouped rows with inset band headings and hidden Yes/No text behind every icon. The header row sticks; the highlighted plan gets a faint accent band. On narrow containers a radio plan picker shows one column at a time — CSS only.

Native table + radios + :has() blocks/site/comparison-table.tsx, blocks/site/registry-2.ts, styles/blocks.csstheme · material · accent · density · font

Compare

Every plan, line by line

Show plan
Every plan, line by line
FeatureSolo$29 / monthStartStudio$79 / monthStartGroupCustomTalk to sales
Booking
Calendars1Up to 8Unlimited
Deposits and prepaymentCard payments through iyzico; refunds from the dashboard.NoYesYes
Waiting listNoYesYes
Messaging
WhatsApp reminders300 / mo2,000 / moUnlimited
SMS fallbackNoYesYes
Account
Single sign-onNoNoYes
Audit logWho moved, cancelled or refunded what, and when.No30 days1 year
Account managerNoNoYes

Installation

$ pnpm add @vamos-ui/react

The whole kit as one package — get updates by bumping the version. Add the styles to globals.css: @import "@vamos-ui/react/styles.css";

Usage

import { ComparisonTable } from "@vamos-ui/react/blocks";

<ComparisonTable
  title="Every plan, *line by line*"
  columns={[{ name: "Solo" }, { name: "Studio", highlight: true }, { name: "Group" }]}
  groups={[{ title: "Booking", rows: [
    { feature: "Calendars", values: ["1", "Up to 8", "Unlimited"] },
    { feature: "Deposits", hint: "Card payments through iyzico.", values: [false, true, true] },
  ] }]}
/>

Examples

Versus (agency vs. template)

Two columns everywhere, the end column muted. Extra columns are ignored.

Why custom

A built site vs. a template

A built site vs. a template
FeatureBuilt with VamosTheme marketplace template
Loads in under 2 s on 4GYesNo
Booking flowBuilt in, with depositsThird-party plugin
Turkish and English URLsYesPaid add-on
KVKK-ready consent bannerYesNo
Who fixes it at 9 pm on a FridayWe doA support forum

Phone width: plan picker

Below 42rem container width a fieldset of radios picks the visible plan (highlighted plan preselected); arrow keys switch plans.

Compare memberships

Show plan
Compare memberships
FeatureDay pass₺1,450Monthly₺4,200 / moYearly₺39,000 / yr
Included
Hammam and saunaYesYesYes
Pool hours10:00–18:00All dayAll day
Massage discountNo10%20%
Guest passesNo1 / month2 / month

API

ComparisonTable

PropTypeDefault
variant
table: 2–5 plans with picker; versus: two columns.
"table" | "versus""table"
columns
2–5 column headers; more are dropped (dev warning).
{ name; note?; cta?; highlight? }[]—
groups
true → check + “Yes”, false → dash + “No”, null → “—”, string → the value.
{ title?; rows: { feature; hint?; values: (boolean | string | null)[] }[] }[]—
caption
Table caption for screen readers. Default: the title.
string—
eyebrow / title / lead
Section header.
ReactNode—
labels / locale
Yes, No, Feature, Show plan…
Partial<Site2Labels> / string—
theme / anchor / id / className / headingLevel / components / editMode
Shared block props.
BlockBaseProps—