Invite Your TeamPRO

A team setup section pairing a soft panel with a working invite row, a role picker, and a plain-language table of what each role can reach, with a bordered list of who is already on the account and whether they have accepted, closing on a seat meter that fills one tick per seat taken.

Onboarding37: Invite Your Team

A team setup section pairing a soft panel with a working invite row, a role picker and a plain-language table of what each role can reach, with a bordered list of who is already on the account and whether they have accepted, closing on a seat meter that fills one tick per seat taken.

Upgrade to Pro

Pro blocks install through the shadcn CLI with your license key and ship their full source. Docs and live previews stay open to everyone, so you can read every block's details first.

Upgrade Now

Installation

Swap YOUR_EMAIL and YOUR_KEY for the email and license key on your account. Find your license key on your account page.

Radix flavor

bash
npx shadcn add "https://ui.beste.co/r/onboarding37?email=YOUR_EMAIL&license_key=YOUR_KEY"

Base UI flavor

bash
npx shadcn add "https://ui.beste.co/r-base/onboarding37?email=YOUR_EMAIL&license_key=YOUR_KEY"

This installs the block to components/beste/block/onboarding37.tsx, the shadcn/ui input and select components it depends on, and the badge23 and button21 components it uses for the eyebrow and the invite action.

Quick start

The installed file exports onboarding37Demo alongside the block: the exact props behind the preview above. Spread it to get a working section in one line.

tsx
import { Onboarding37, onboarding37Demo } from "@/components/beste/block/onboarding37";

export default function TeamPage() {
  return <Onboarding37 {...onboarding37Demo} />;
}

Then replace the demo with your own props. Written out, a trimmed setup looks like this:

tsx
import { Onboarding37 } from "@/components/beste/block/onboarding37";

export default function TeamPage() {
  return (
    <Onboarding37
      badge={{ label: "Bring the team in" }}
      heading="Invite people to the job they actually do"
      description="Roles are written in plain language."
      form={{
        emailLabel: "Work email",
        emailPlaceholder: "colleague@practice.com",
        roleLabel: "Their role",
        roleOptions: ["Reception", "Clinician", "Practice manager"],
        submitLabel: "Send the invite",
        finePrint: "Invites expire after seven days.",
      }}
      rolesTitle="What each role can reach"
      roleNotes={[
        { name: "Reception", description: "The clinic list, bookings, and messaging." },
        { name: "Finance", description: "Invoices, payments, and exports. No member records." },
      ]}
      listTitle="Already on the account"
      teammates={[
        {
          name: "Elena Rourke",
          email: "elena@example.com",
          role: "Practice manager",
          state: "accepted",
          avatar: { src: "/people/elena.jpg", alt: "Portrait of Elena Rourke" },
        },
        { name: "Noah Reyes", email: "noah@example.com", role: "Locum", state: "pending" },
      ]}
      stateLabels={{ accepted: "Active", pending: "Invited" }}
      seats={{
        label: "Seats in use",
        used: 4,
        total: 10,
        unitLabel: "of 10 on this plan",
        note: "Adding a seat mid-month is prorated.",
      }}
    />
  );
}

Props

PropTypeDefaultDescription
badge{ label: string }Eyebrow above the hairline rule, rendered through Badge23
headingstringSection heading in the left column of the header
descriptionstringSupporting paragraph, right-aligned from md up
formInviteFormLabels, placeholders and role options for the invite row
rolesTitlestringHeading above the role explanations
roleNotesRoleNote[][]What each role can reach, in plain language
listTitlestringHeading above the existing team list
teammatesTeammate[][]Who is already on the account
stateLabelsRecord<InviteState, string>The word shown for accepted and pending
seatsSeatUsageSeat meter figures and its caveat
classNamestringExtra classes for the outer section
ts
type InviteState = "accepted" | "pending";

type InviteForm = {
  emailLabel: string;
  emailPlaceholder: string;
  roleLabel: string;
  roleOptions: string[];
  submitLabel: string;
  finePrint: string;
};

type RoleNote = {
  name: string;
  description: string;
};

type Teammate = {
  name: string;
  email: string;
  role: string;
  state: InviteState;
  avatar?: { src: string; alt: string };
};

type SeatUsage = {
  label: string;
  used: number;
  total: number;
  unitLabel: string;
  note: string;
};

Behavior notes

Wiring the form up

The invite row renders its fields and leaves submission to you. For validation, error states and submit handling, the patterns in React Hook Form, TanStack Form, and Formisch cover this shape of form, including the select.

More Onboarding blocks

View all Onboarding
PRO

onboarding14

Workspace Setup with Team Invite

Combined onboarding card for creating a workspace with name and URL slug, plus a team invite section with email inputs. Perfect for SaaS apps that require team collaboration setup.

PRO

onboarding34

Role Based Getting Started

A getting-started section whose role pills swap a sticky summary column and the numbered steps beside it, each step carrying its own title, explanation, and honest time estimate.

PRO

onboarding33

Interactive Setup Checklist

A setup panel pairing a soft progress column, where an oversized percentage and accent bar react to what is ticked, with hairline checklist rows that each carry a description and a jump-in link.

FREE

onboarding43

Guided Workspace Setup

A two-column setup section: the pitch and what each answer changes on the left, and a one-question-at-a-time wizard on the right that ends in a review of everything it is about to create.

PRO

onboarding23

Security Setup

Onboarding screen for configuring account security including two-factor authentication, recovery email, and backup codes. Perfect for apps that prioritize security during onboarding.

PRO

onboarding15

Integration Connector Grid

Onboarding screen with a grid of available integrations showing connection status and connect/skip actions. Perfect for apps that rely on third-party services like Slack, GitHub, and Google.