Cal.comdesign-system

Event Registration Section

Public event sidebar card — compose with CardFrame parts, fact rows, and StatusMark.

Compose the public Cal Event registration card from EventRegistrationSection parts. Branching (registration state, sign-in, which rows to show) lives in the feature layer — see resolveEventRegistrationPresentation and cal-events-registrations.

Ownership

Feature — not @coss/ui/shared. Compound parts live under packages/features/cal-events because registration copy, registration-state branching, and i18n wiring belong to Cal Events. Production renders them through EventRegistrationCard (event-registration-card.tsx), which composes the parts, the named facts and the resolver from the public page's data.

Anatomy

CardFrame header (py-3), optional fact rows, optional centered status (StatusMark + title + description), then a full-width action stack. Put identity under the action inside EventRegistrationSectionActions.

EventRegistrationSection · compound composition
Registration
8 spots remainingRegister before it fills up

Joining as pro@example.com

Typical open RSVP · signed in

Facts

Spots remaining, approval required, price — each is an EventRegistrationSectionFact inside EventRegistrationSectionFacts. EventRegistrationSectionFact is the generic row: you pass the icon, title and subtitle. Below it are the specific facts made for each case; they pick the icon and copy for you, so use those and reach for the generic row only when there is no specific fact.

EventRegistrationSectionFact
8 spots remainingRegister before it fills up
Approval requiredThe host must approve your request before you're in
$25.00Paid event
From $25.00Depends on your location choice
EventRegistrationSectionFact

Price fact

EventRegistrationSectionFactPrice renders the price row. Pass it the event's cheapest price and whether the locations charge different amounts or include a free one; the public event page already has these on data. Price fact formats the amount and picks the wording. Free events render nothing.

Passing the props
EventRegistrationSectionFactPrice · fixed, from, freeTo
$25.00Paid event
From $25.00Depends on your location choice
Free – $25.00Depends on your location choice

Spots remaining fact

EventRegistrationSectionFactSpotsRemaining renders the seats-left row. Pass it the number of spots remaining. On the public event page getCalEventPublicData counts confirmed guests against the event's seat limit and puts the result on data.capacity.spotsRemaining. Spots remaining fact picks the one-spot or many-spots wording and adds the same subtitle under both. It renders nothing when the event is full or has no capacity limit.

Passing the props
EventRegistrationSectionFactSpotsRemaining · many, one
8 spots remainingRegister before it fills up
One spot remainingRegister before it fills up

Approval required fact

EventRegistrationSectionFactApprovalRequired renders the row telling guests the host has to approve them. It takes no data; the public event page shows it when data.requiresApproval is true.

Passing the props
EventRegistrationSectionFactApprovalRequired
Approval requiredThe host must approve your request before you're in

Status

Post-join status

Playground

Every state the card is meant to render. Cancelled events render nothing — the page already owns that state.

Open RSVP

Register

Unlimited, free, no approval. Anonymous visitor.

Registration

Register · signed in (form)

Same CTA as anonymous. Footer is email only — no name, no avatar. Used when one-click cannot run (questions, public names, multi-location, missing profile name).

Registration

Joining as pro@example.com

Register in one click

Signed-in, complete identity, no extra questions, single location, not approval, guest names off.

Registration

Joining as pro@example.com

One-click submitting

Registration

Joining as pro@example.com

Capacity & approval

Spots remaining

Registration
8 spots remainingRegister before it fills up

One spot remaining

Registration
One spot remainingRegister before it fills up

Approval required

Registration
Approval requiredThe host must approve your request before you're in

Approval + spots

Registration
8 spots remainingRegister before it fills up
Approval requiredThe host must approve your request before you're in

Signed in · not registered

One-click + price

One-click allows a single priced location. From/Free–$X need multiple locations, so they cannot one-click.

Registration
$25.00Paid event

Joining as pro@example.com

One-click + spots

Registration
8 spots remainingRegister before it fills up

Joining as pro@example.com

One-click + price + spots

Registration
$25.00Paid event
8 spots remainingRegister before it fills up

Joining as pro@example.com

Request to join

Approval blocks one-click. Footer is still Joining as email.

Registration
Approval requiredThe host must approve your request before you're in

Joining as pro@example.com

Request to join + spots

Registration
8 spots remainingRegister before it fills up
Approval requiredThe host must approve your request before you're in

Joining as pro@example.com

Join waitlist

Registration

Joining as pro@example.com

Sold out

Registration
Sold out
This event is full

Registration closed

Closed copy, not a button. No footer: the viewer can no longer join.

Registration
Registration closed
This event has already started

Closed / full / cancelled

Sold out

Full, waitlist off. Spots row is omitted when remaining is 0.

Registration
Sold out
This event is full

Join waitlist

Full, waitlist on.

Registration

Sold out + approval

Approval wins: still Request to join.

Registration
Sold out
This event is full, but you can still request to join.

Registration closed

Event has started. CTA is copy, not a button.

Registration
Registration closed
This event has already started

Cancelled

Today still paints a cancelled CTA. The page already has a cancelled Alert.

No registration card

Registration closed (ended)

Event has ended. CTA is copy, not a button.

Registration
Registration closed
This event has ended

Already joined · signed in

You're in

Footer stays: Joining as email, not name/avatar.

Registration
You're in!
Your spot is confirmed. Check your email for event details and updates

You're in + spots

Spots row is not suppressed after you join.

Registration
You're in!
Your spot is confirmed. Check your email for event details and updates

You're in + price

Registration
You're in!
Your spot is confirmed. Check your email for event details and updates

You're in + approval row

requiresApproval is still true on the event after you are confirmed.

Registration
You're in!
Your spot is confirmed. Check your email for event details and updates

Pending approval

Registration
Pending approval
Registration received — the host will review your request

Pending + spots

Registration
Pending approval
Registration received — the host will review your request

On the waitlist

Registration
You're on the waitlist
We'll email you if a spot becomes available

Pay now

Registration

Complete payment to confirm your spot

Joining as ana@example.com

Pay now + spots

Registration

Complete payment to confirm your spot

Joining as ana@example.com

Payment unavailable

Registration
Checkout unavailable
This checkout is no longer available

You're in

Restored from the RSVP cookie: no footer, but the ticket and cancel actions are theirs.

Registration
You're in!
Your spot is confirmed. Check your email for event details and updates

You're in + price

Registration
You're in!
Your spot is confirmed. Check your email for event details and updates

Pending approval

Registration
Pending approval
Registration received — the host will review your request

On the waitlist

Registration
You're on the waitlist
We'll email you if a spot becomes available

Pay now

Registration

Complete payment to confirm your spot

Payment unavailable

Registration
Checkout unavailable
This checkout is no longer available

Host

You're hosting

Footer hidden. No sales rows.

Registration

You're hosting this event

Hosting + spots

Registration
8 spots remainingRegister before it fills up

You're hosting this event

Hosting a paid event

Registration
$25.00Paid event
8 spots remainingRegister before it fills up

You're hosting this event

Hosting + approval

Registration
Approval requiredThe host must approve your request before you're in

You're hosting this event

Hosting + price + spots + approval

Registration
$25.00Paid event
8 spots remainingRegister before it fills up
Approval requiredThe host must approve your request before you're in

You're hosting this event

Host on a cancelled event

Today still paints a cancelled CTA. Then drops the card, same as a guest.

No registration card

Parts

Internationalization

The generic parts do not call the i18n layer; the named facts do.

Production wiring lives in apps/web (or a feature component using useLocale), matching event-public-view.tsx. Key: cal_events_joining_as in common.json.

Call sites

Example URLs

Source