Booker Event Information
Anatomy, states, and display conditions for the month-view Booker's event-information pane.
This page is a migration blueprint for the month-view Booker's left event-information pane. The current Cal Booker defines component order and display conditions; the previews show the target UI. Week and column layouts are outside this page's scope.
Anatomy
The map shows order and spacing. Labels link to each component. Conditional components are combined for reference; no booking flow renders all of them.
Only the event-information pane is included; the calendar, time slots, and booking form are outside this page's scope. The loading state replaces the information body, while hideEventTypeDetails removes the complete pane.
On mobile, the pane is the full-width top section with 16px body padding and two rounded banner corners. On desktop, these previews show it as a 280px left rail with 24px padding and a square trailing edge.
Availability badges beneath each component heading summarize where the behavior is possible. Web app means the current Cal Booker supports it. API v2 means the API exposes the data needed to reproduce it, while Partial means some required data is missing. Local state and Component API identify behavior that is not owned by either backend. Exact fields and differences are listed in Data contracts.
Header
The header displays the event type's banner. When the event type has no banner, Cal falls back to the organization banner. Nothing is rendered when event details are hidden or neither banner is available.

Host identity
The host identity appears before the event title and identifies the person or team responsible for the event.
Individual event
Shows the user's avatar and name.
Alex Rivera
Collective event
Cal displays at most four avatars and replaces the remaining identities with a +N avatar. A configured team or organization avatar appears first and counts toward that limit.
Product Team
For the target UI, when no shared team or profile name is available, use the first member's name and the remaining count instead of Cal's current unbounded list. The +N avatar opens the hidden member names.
Alex Rivera and 5 others
Round robin event
Hides the possible member avatars and shows the team or profile identity instead.
Product Team
Round robin without an avatar
When a round-robin event hides the organization or team avatar, Cal displays only the profile name.
When roundRobinHideOrgAndTeam is enabled, Cal hides both the avatar and profile name; the current Booker retains a small vertical spacer in their place.
Product Team
Event title
The event title appears after the host identity whenever event information is visible. Cal uses the translated title for the attendee's locale when one is available.
Default title
30 Minute Meeting
Long title
Long titles wrap within the pane instead of being truncated.
Planning and strategy session for a new product launch
Event description
The event description appears below the title when a description is available. Cal prefers the translated description for the attendee's locale and renders nothing when the description is empty.
Short description
A focused conversation about your goals, current challenges, and the next steps we can take together.
Long description
Long descriptions remain within a 180px scrollable region. A gradient indicates when more content is available above or below the visible area.
Use this session to review the launch plan and leave with a clear set of next steps.
We will cover:
- Goals, audience, and measures of success
- Scope, milestones, and open decisions
- Ownership and immediate next actions
Please bring any research, constraints, or questions that would help the group make decisions. You can also share relevant links in advance.
At the end of the session, we will recap the decisions and confirm who owns each follow-up.
Rich formatting
Descriptions can combine headings, links, ordered and unordered lists, emphasis, quotes, and inline code. The content remains constrained by the same scrollable region.
Heading h1
Body text under heading h1.
Heading h2
Body text under heading h2 with a link.
Heading h3
Body text with strong emphasis, italic emphasis, and inline code.
- Confirm the goal and audience
- Share open decisions and known constraints
We will leave the call with owners and next steps.
Former time
The former time appears only while rescheduling, when Cal has both the reschedule identifier and the original booking data. It shows the original date and time with a strikethrough before the newly selected time.
Tuesday, September 8, 2026
10:00 am
Selected time
The selected time appears once a timeslot has been chosen. During rescheduling it follows the former time. Cal formats it using the attendee's timezone, locale, time format, and selected duration.
10:00 am–10:30 am
Confirmation requirement
This row appears when the event type requires the host to confirm new bookings manually.
Duration
The duration row is always present. Its content changes according to the event type's duration configuration and the current Booker step.
Static duration
A single-duration event displays its formatted length. Multiple-duration and dynamic events use the same static presentation during the booking step or when the duration selector is hidden.
Selectable duration
Before the booking step, multiple-duration and dynamic events allow the attendee to choose a duration unless the selector is hidden.
Recurrence
The recurrence row appears for recurring events, except while rescheduling. Its content changes when the Booker moves from time selection to the booking step.
Occurrence count
Before a time is selected, the attendee can choose how many occurrences to book, up to the event type's configured maximum.
Invalid occurrence count
Cal keeps an out-of-range entry visible, uses the configured maximum for the booking state, and displays validation feedback.
Resolved dates
During the booking step, Cal replaces the count control with the resolved occurrence dates. It shows the first five dates, exposes any remaining dates in a popover, and marks daylight-saving time shifts.
Tue, Sep 15, 10:00 am
Tue, Sep 22, 10:00 am
Tue, Sep 29, 10:00 am
Tue, Oct 6, 10:00 am
Tue, Oct 13, 11:00 amTime shift
Location
The location row is hidden when an event has no locations, is an instant meeting, or lets each host provide their own location.
Single location
A single configured location is displayed directly with its provider or location icon.
Provider location
A conferencing location displays the provider's own icon instead of the generic location icon.
Multiple locations
Multiple locations are summarized as options. Hovering or focusing the row reveals the choices, which the attendee selects during the booking step.
Price
The price row appears only when the event's resolved payment amount is greater than zero.
Standard currency
Standard currencies use the localized amount and credit-card icon.
Bitcoin
Bitcoin prices are displayed in satoshis with the dedicated sats symbol.
Timezone
The timezone row is always present with visible event details. During time selection it is editable unless the event locks the booking-page timezone; during the booking step it becomes static text.
Selectable timezone
Implementation note: Refactor TimezoneCombobox to accept a custom trigger before migrating this state. The Booker should reuse its timezone options, canonicalization, search, and popup while preserving the compact trigger shown below.
Static timezone
After a time is selected, the timezone becomes static text. Use the same target treatment for locked events; current Cal instead disables the selector. Resolve the value from the event's locked timezone, its schedule timezone, or the current timezone.
Reschedule host preference
This is the post-choice editor for a round-robin reschedule that allows host choice. It appears after the person rescheduling completes the mandatory initial-choice dialog. It is hidden for fresh bookings, non-round-robin events, events where host choice is disabled, and rerouting flows. When event details are hidden or the separate mobile slot dialog owns the controls, move this same component into the time-slot pane and make it fill the available row.
Seat availability
Seat availability appears during the booking step when the event has a seat limit and at least one seat is already booked. The event type decides whether Cal exposes the exact count.
Exact availability
Available
When exact counts are hidden and fewer than half the seats are booked, Cal displays a neutral availability message.
Filling fast
When exact counts are hidden, Cal shows this warning after at least half the seats are booked.
Almost full
The stronger warning appears after at least 83% of the seats are booked.
Loading state
While event information is pending, the pane replaces its content with placeholders that preserve the loaded layout's structure.
Custom content slot
Cal accepts caller-owned React content after the standard event-information rows through eventMetaChildren. There is no current in-app usage or fixed visual composition to preview, so consumers should treat this as an extension point rather than another standard Booker component.
Complete examples
These examples show the shell populated with a representative subset of components. Refer to the component map and the individual sections above for the complete set of possible content.
With a banner
When a banner is available, it sits flush against the top edge and the padded information body overlaps its lower edge.

Alex Rivera
30 Minute Meeting
A focused conversation about your goals and the next steps we can take together.
Without a banner
Without a banner, the same information body starts at the shell's standard top padding.
Alex Rivera
30 Minute Meeting
A focused conversation about your goals and the next steps we can take together.
Profile name only
A round-robin event can hide the team or organization avatar and retain only the shared profile name.

Product Team
30 Minute Meeting
A focused conversation about your goals and the next steps we can take together.
Multiple avatars
A collective event can show its shared identity followed by member avatars. The stack displays at most four avatars; +N opens the hidden member names.

Product Team
30 Minute Meeting
A focused conversation about your goals and the next steps we can take together.
Data contracts
Use this map when wiring either Booker. Unless a row says otherwise, the Cal fields come from the PublicEventType returned by viewer.public.event; production booking routes may server-load the same model. API v2 event fields refer to GET /v2/event-types (2024-06-14), while slot fields refer to GET /v2/slots (2024-09-04). Local state is part of the Booker adapter, not either transport.
The current atom normalizes the basic identity, title, description, duration, location, and selected-slot fields. Its hand-written event type omits several fields that the API already returns. It also fetches banner and public display-name data from tRPC because the generic event-types response does not provide the full public identity.
| Component | Cal Booker / tRPC | API v2 / atom | Parity rule |
|---|---|---|---|
| Header | bannerUrl, falling back to the organization banner before it reaches Booker | team.bannerUrl; the generic event-type response does not expose the complete event and organization fallback | Partial. The current atom supplements API v2 with a public-event tRPC request. |
| Host identity | profile, entity, subsetOfUsers, and schedulingType | Personal events use users; team events use hosts, team, and schedulingType | Implemented. Normalize both shapes into one profile plus an ordered avatar list, then apply the display rules above. |
| Event title | title and locale-matched fieldTranslations | title | Partial. The title is direct; translated fields are absent from the generic API response. |
| Event description | description and locale-matched fieldTranslations | description | Partial. The description is direct; translated fields are absent from the generic API response. |
| Former time | rescheduleUid plus server-loaded bookingData.startTime and bookingData.endTime | GET /v2/bookings/{uid} exposes start and end | Not wired in the atom. Normalize the API names and expose this only through an authorized reschedule flow. |
| Selected time | Booker-store selectedTimeslot, selectedDuration, and timezone; availability comes from viewer.slots.getSchedule or API v2 for eligible team events | Selected /v2/slots entry's start, plus local duration and timezone state | Implemented. This is derived interaction state, not an event-type field. |
| Confirmation requirement | requiresConfirmation | confirmationPolicy | Not wired in the atom. Normalize an enabled policy to the boolean presentation state. |
| Duration | length, metadata.multipleDuration, metadata.hideDurationSelectorInBookingPage, and isDynamic | lengthInMinutes, lengthInMinutesOptions, and metadata | Implemented. Normalize the field names and keep selection in local state. |
| Recurrence | recurringEvent.{interval,count,freq} plus local occurrence count and selected slot | recurrence.{interval,occurrences,frequency} plus local occurrence count and selected slot | Not wired in the atom. Rename occurrences to count and normalize the frequency enum. |
| Location | locations, isInstantEvent, and enablePerHostLocations | locations and isInstantEvent; the generic response omits enablePerHostLocations | Partial. Basic locations are implemented; the per-host visibility condition needs more data. |
| Price | price, currency, and payment-app data resolved from metadata | price, currency, and metadata | Not wired in the atom. Resolve payment-app overrides before creating the display value. |
| Timezone | Booker-store timezone; locked events use lockTimeZoneToggleOnBookingPage, lockedTimeZone, then schedule.timeZone | Local timezone plus lockTimeZoneToggleOnBookingPage; the generic response exposes scheduleId, not the locked timezone value | Partial. Selection and display exist; locked-timezone parity needs the missing value. |
| Reschedule host preference | allowRRHostChoiceOnReschedule, schedulingType, reschedule and rerouting context, and local rescheduleWithSameHost | Team event types expose allowRRHostChoiceOnReschedule and schedulingType; the reschedule context and choice remain local | Not wired in the atom. The adapter must apply the complete display condition, not only the event flag. |
| Seat availability | seatsPerTimeSlot, seatsShowAvailabilityCount, and the selected slot or booking attendee count | Event type seats or legacy seat fields; slots expose seatsBooked, seatsRemaining, and seatsTotal | Not wired in the atom. Preserve the selected slot's seat counts instead of reducing it to a start time. |
| Loading state | event.isPending | Event, slot, and booking request state | Local. One loading model should describe which pane data is pending. |
| Custom content slot | Caller-owned eventMetaChildren | No transport field and no current atom slot | Component API gap. Decide whether both Bookers need the same extension point before adding it. |
Cal also has an internal GET /v2/atoms/event-types/{eventSlug}/public endpoint that returns the same PublicEventType used by tRPC. The current atom does not use it. It would make most event rows direct and remove the separate tRPC banner request, but it is excluded from the public API documentation and must be explicitly adopted as a supported atom contract before the atom depends on it. Slots, bookings, and local interaction state would still remain separate contracts.
In the Coss repository, the current normalization lives in apps/ui/registry/default/atoms/lib/booker/use-booker.ts and apps/ui/registry/default/atoms/lib/booker/utils.ts; its API clients live in apps/ui/registry/default/lib/cal-api/.
Implementation references
These files define the documented component order, display conditions, and transport contracts.
| Area | Cal source |
|---|---|
| Left pane shell, width, and banner placement | apps/web/modules/bookings/components/booker.tsx, packages/features/bookings/Booker/config.ts |
| Pane composition | apps/web/modules/bookings/components/EventMeta.tsx |
| Header visibility and banner fallback | apps/web/modules/bookings/components/booker.tsx |
| Host identity states | apps/web/modules/bookings/components/event-meta/Members.tsx |
| Event title | apps/web/modules/bookings/components/event-meta/Title.tsx |
| Event description visibility, translation, and scrolling | apps/web/modules/bookings/components/EventMeta.tsx, apps/web/modules/bookings/components/ScrollableWithGradients.tsx |
| Former time during rescheduling | apps/web/modules/bookings/components/EventMeta.tsx |
| Selected time | apps/web/modules/bookings/components/EventMeta.tsx, packages/features/bookings/Booker/utils/dates.tsx |
| Confirmation requirement and detail order | apps/web/modules/bookings/components/event-meta/details.tsx |
| Duration states | apps/web/modules/bookings/components/event-meta/Duration.tsx |
| Recurrence states | apps/web/modules/bookings/components/event-meta/occurences.tsx |
| Location states | apps/web/modules/bookings/components/event-meta/AvailableEventLocations.tsx |
| Price and currency icon | apps/web/modules/bookings/components/event-meta/Price.tsx, apps/web/modules/bookings/components/event-meta/PriceIcon.tsx |
| Timezone states | apps/web/modules/bookings/components/EventMetaTimezoneRow.tsx, packages/features/timezone/components/timezone-combobox.tsx |
| Reschedule host preference | apps/web/modules/bookings/components/reschedule-host-selector.tsx, apps/web/modules/bookings/hooks/use-reschedule-host-choice.ts |
| Seat availability | apps/web/modules/bookings/components/EventMeta.tsx, apps/web/modules/bookings/components/SeatsAvailabilityText.tsx |
| Loading state | apps/web/modules/bookings/components/event-meta/Skeleton.tsx |
| Custom content slot | packages/features/bookings/Booker/types.ts, apps/web/modules/bookings/components/EventMeta.tsx |
| Cal public-event tRPC contract | apps/web/trpc/server/routers/publicViewer/procedures/event.ts, packages/features/eventtypes/lib/getPublicEvent.ts |
| API v2 event-type contract | packages/platform/types/event-types/event-types_2024_06_14/outputs/event-type.output.ts |
| API v2 slot contract | packages/platform/types/slots/slots-2024-09-04/outputs/slots.output.ts |
| Atom public-event endpoint | apps/api/v2/src/modules/atoms/controllers/atoms.event-types.controller.ts, apps/api/v2/src/modules/atoms/services/event-types-atom.service.ts |
Example URLs
Not exhaustive—open these paths locally to see the event-information pane in the complete Booker.
| Path | Notes |
|---|---|
/[user]/[type] | Individual event |
/team/[slug]/[type] | Collective or round-robin event |
On This Page