Staaarter

Billing Role Permissions Pricing

A matrix-style table showing which team roles, such as Admin, Billing, and Member, have access to which billing features, such as invoices, payment methods, and plan changes. Renders as a real table with check and minus icons on wider screens and switches to a stacked per-role list on narrow ones so nothing needs horizontal scrolling. Built for enterprise team settings and billing documentation pages.

By Staaarter Team
Billing
Updated August 3, 2026
Docs
Live preview

Docs

Installation

A real shadcn registry command, not a copy-paste stand-in: it fetches this block plus its dependencies and any missing npm packages, and installs them straight into your project.

npx shadcn add https://staaarter.com/r/billing-role-permissions-pricing.json

Prefer not to use the CLI? Copy the source from the Code toggle above into src/components/blocks/billing/billing118.tsx instead.

Usage

The file also exports billing118Demo, the exact props behind the preview above. Spread it to get a working section in one line, then replace it with your own data.

import { Billing118, billing118Demo } from "@/components/blocks/billing/billing118";

export default function Page() {
  return <Billing118 {...billing118Demo} />;
}

Props

PropTypeDefaultDescription
headingstring"Role permissions"Heading shown above the matrix.
descriptionstringnoneOptional supporting text under the heading.
rolesPermissionRole[]noneRoles rendered as table columns, in the order given.
featuresPermissionFeature[]noneFeatures rendered as table rows, in the order given.
classNamestringnoneExtra classes for the outer card.

Types

interface PermissionRole {
  id: string;
  name: string;
  description?: string;
}

interface PermissionFeature {
  id: string;
  label: string;
  /** Keyed by role id. */
  access: Record<string, boolean>;
}

Behavior notes

  • On viewports at sm and above the component renders a real table with role='grid' and matching row/gridcell roles for screen reader navigation.
  • Below sm it switches to a stacked list grouped by role, each with its own list of features and a check or minus icon, so nothing scrolls horizontally on phones.
  • Access is looked up as feature.access[role.id]; a missing key is treated the same as false and renders a minus icon.
  • Every icon carries an aria-label describing the specific role/feature access it represents, in addition to the row and column headers already giving that context visually.
  • The number of columns and rows is entirely driven by the length of the roles and features arrays, there's no hardcoded 3x3 assumption.

Frequently asked questions