* chore: refactor config files to prevent migration tool errors * refactor: upgrade with the tailwind migration tool * chore: restore pre-commit command + mc * refactor(wip): update dependencies and migrate to Tailwind CSS v4 (mainly web) * chore: resolve Tailwind v4 migration conflicts from merging main * chore: remove unused Tailwind packages from config and update dependencies for v4 migration * chore: uncomment Tailwind CSS utility classes in globals.css * fix: resolve token conflicts between calcom and coss ui * fix: textarea scrollbar * Fix CUI-16 * fix: added @tailwindcss/forms plugin and cleaned up CSS classes in various components to remove unnecessary dark mode styles * fix: selects and inputs of different sizes * fix: remove unnecessary leading-20 class from modal titles in various components * fix: update Checkbox component styles to remove unnecessary border on checked state * fix: clean up styles in RequiresConfirmationController, Checkbox, and Radio components to enhance consistency * fix: update button and filter component styles to remove unnecessary rounded classes for consistency * fix: calendar * fix: update KBarSearch * fix: refine styles in Empty and Checkbox components for improved consistency * Fix focus state email input * fix: update button hover and active states to use 'not-disabled' instead of 'enabled' * fix: line-height issues * fix: update class name for muted background in BookingListItem component * fix: sidebar spacing * chore: update class names to use new Tailwind CSS color utilities * fix embed * chore: upgrade Tailwind CSS to version 4.1.16 and update related dependencies * Map css variables and add a playground test for heavy css customization * suggestion for coss-ui * refactor: update CSS variable usage and clean up styles - Replace instances of `--cal-brand-color` with `--cal-brand` in embed-related HTML files. - Remove the now-unnecessary `addAppCssVars` function from the embed core. - Import theme tokens in the embed core styles for better consistency. - Clean up whitespace and formatting in CSS files for improved readability. - Add a comment in `tokens.css` regarding its usage in both embed and webapp contexts. * Handle within tokens.css instead of fixing coss-ui * Remove initial, not needed. Also, remove tailwind.config.js as tailwidn scans the html automaically * fix: examples app breaking * fix: modal not resizing correctly * feat: upgrade atoms to tailwind v4 * fix: atoms build breaking * fix: atoms build breaking * chore: upgrate examples/base to tailwind 4 * chore: update globals.css * fix: add missing scheduler css variables * fix: PlatformAdditionalCalendarSelector * chore: update global styles * chore: update tailwindcss and postcss dependencies to stable versions * chore: remove unneeded class * fix: dialog and toast animation * fix: replace flex-shrink-0 with shrink-0 for consistent styling in various components * fix: dialog modal for Apple connect * add margin in SaveFilterSegmentButton * Fix radix button nested states * add cursor pointer to buttons but keep dsabled state * Fix commandK selectors and adds cursor pointer * Fix teams filter * fix - round checkboxes * fix filter checkbox * fix select indicator's margin * command group font size * style: fix badge and tooltip radius * chore: remove unneeded files * Delete PR_REVIEW_MANAGED_EVENT_REASSIGNMENT.md * remove ui-playground leftover * fix: add missing react phone input styles in atoms * Delete managed-event-reassignment-flow-and-architecture.mermaid * fix: inter font not loading * Add theme to skeleton container so that it can support dark mode * fix: create custom stack-y-* utilities post tw4 upgrade * fix: typo * fix: atoms stack class + remove unused css file * fix default radius valiue * fix space-y in embed * fix skeleton background * Hardcode radius values to match production * fix border in embed * add missing externalThemeClass * feat: create a custom stack-y-* utility * fix: add stack utility to atom global css * fix: Skeleton loader class modalbox * Add stack-y utility in embed * fix: add missing stack utilities in atoms globals.css * update yarn.lock * add popover portla * update --------- Co-authored-by: Sean Brydon <sean@cal.com> Co-authored-by: Hariom Balhara <hariombalhara@gmail.com> Co-authored-by: Ryukemeister <sahalrajiv6900@gmail.com> Co-authored-by: cal.com <morgan@cal.com> Co-authored-by: Eunjae Lee <hey@eunjae.dev> Co-authored-by: Anik Dhabal Babu <adhabal2002@gmail.com>
291 lines
21 KiB
Plaintext
291 lines
21 KiB
Plaintext
---
|
|
title: "Booker"
|
|
---
|
|
|
|
The booker atom is a dynamic component that facilitates the booking process for users. It allows individuals to easily select available time slots and confirm their participation in various events, streamlining the scheduling experience. It is one of the most important atoms and a critical piece of our scheduling system.
|
|
|
|
Below code snippet can be used to render the booker atom
|
|
|
|
```js
|
|
import { Booker } from "@calcom/atoms";
|
|
|
|
export default function Booker( props : BookerProps ) {
|
|
return (
|
|
<>
|
|
<Booker
|
|
eventSlug={props.eventTypeSlug}
|
|
username={props.calUsername}
|
|
onCreateBookingSuccess={() => {
|
|
console.log("booking created successfully");
|
|
}}
|
|
/>
|
|
</>
|
|
)
|
|
}
|
|
```
|
|
|
|
For a demonstration of the booker atom, please refer to the video below.
|
|
|
|
<p></p>
|
|
|
|
<iframe
|
|
height="315"
|
|
style={{ width: "100%", maxWidth: "560px" }}
|
|
src="https://www.loom.com/embed/73dbb943cef0409c9bc57d5050453a6e?sid=45575c09-4786-486e-99f9-6cf7f4e8db50"
|
|
frameborder="0"
|
|
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
|
allowfullscreen="true"
|
|
></iframe>
|
|
|
|
<p></p>
|
|
|
|
It is also possible to change the booker layout into a week or column view, you just need to pass in the view prop the layout you want to use. The layouts are as follows: **MONTH_VIEW,** **WEEK_VIEW** and **COLUMN_VIEW**. Both the week and column layouts come with an Overlay Calendar feature, which allows users to overlay multiple calendars on top of their primary calendar.
|
|
|
|
Below code snippet can be used to render the booker atom with week view
|
|
|
|
```js
|
|
import { Booker } from "@calcom/atoms";
|
|
|
|
export default function Booker( props : BookerProps ) {
|
|
return (
|
|
<>
|
|
<Booker
|
|
view="WEEK_VIEW"
|
|
eventSlug={props.eventTypeSlug}
|
|
username={props.calUsername}
|
|
onCreateBookingSuccess={() => {
|
|
console.log("booking created successfully");
|
|
}}
|
|
/>
|
|
</>
|
|
)
|
|
}
|
|
```
|
|
|
|
For a demonstration of the booker atom along with calendar overlay, please refer to the video below.
|
|
|
|
<p></p>
|
|
|
|
<iframe
|
|
height="315"
|
|
style={{ width: "100%", maxWidth: "560px" }}
|
|
src="https://www.loom.com/embed/554e9ef9f7874cbe9d179b63cc2c601b?sid=fc185a1c-1fb9-4705-a222-8ccd131bd5b6"
|
|
frameborder="0"
|
|
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
|
allowfullscreen="true"
|
|
></iframe>
|
|
|
|
<p></p>
|
|
|
|
We offer all kinds of customizations to the booker atom via props and customClassNames.
|
|
|
|
Below is a list of props that can be passed to the booker atom.
|
|
|
|
<p></p>
|
|
|
|
| Name | Required | Description |
|
|
| :------------------------------ | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
| username | Yes | Username of the person whose schedule is to be displayed |
|
|
| eventSlug | Yes | Unique slug created for a particular event |
|
|
| orgBannerUrl | No | URL of the user's current organization |
|
|
| customClassNames | No | To pass in custom classnames from outside for styling the atom |
|
|
| month | No | The exact month for displaying a user's availability; defaults to the current month |
|
|
| selectedDate | No | Default selected date for which the slot picker opens |
|
|
| startTime | No | Custom start time for the Booker that allows users to decide the first available date. Accepts JavaScript Date object or date string in format `YYYY-MM-DD` (e.g., `"2025-08-20"` or `new Date("2025-08-20")`) |
|
|
| hideBranding | No | For hiding any branding on the booker |
|
|
| isAway | No | Sets the booker component to the away state |
|
|
| allowsDynamicBooking | No | Boolean indicating if the booking is a dynamic booking |
|
|
| bookingData | No | Data for rescheduling a booking passed in via this prop |
|
|
| defaultFormValues | No | Prefilled values for booking form fields like name, email, guests, notes, reschedule reason, etc. |
|
|
| isTeamEvent | No | Boolean indicating if it is a team event |
|
|
| duration | No | Refers to a multiple-duration event type; selects default if not passed |
|
|
| durationConfig | No | Configures selectable options for a multi-duration event type |
|
|
| hashedLink | No | Refers to the private link from event types page |
|
|
| isInstantMeeting | No | Boolean indicating if the booking is an instant meeting |
|
|
| bookingUid | No | Unique ID generated during booking creation |
|
|
| rescheduleUid | No | Unique ID generated during booking creation, same as bookingUid |
|
|
| locationUrl | No | Custom meeting link URL instead of a Cal.com link |
|
|
| firstName | No | First name of the attendee |
|
|
| lastName | No | Last name of the attendee |
|
|
| guests | No | Invite a guest to join a meeting |
|
|
| name | No | Host name |
|
|
| onCreateBookingSuccess | No | Callback function for successful booking creation |
|
|
| onCreateBookingError | No | Callback function triggered on booking creation failure |
|
|
| onCreateRecurringBookingSuccess | No | Callback function for successful recurring booking creation |
|
|
| onCreateRecurringBookingError | No | Callback function triggered on recurring booking creation failure |
|
|
| onCreateInstantBookingSuccess | No | Callback function for successful instant booking creation |
|
|
| onCreateInstantBookingError | No | Callback function triggered on instant booking creation failure |
|
|
| onReserveSlotSuccess | No | Callback function for successful slot reservation |
|
|
| onReserveSlotError | No | Callback function triggered on slot reservation failure |
|
|
| onDeleteSlotSuccess | No | Callback function for successful slot deletion |
|
|
| onDeleteSlotError | No | Callback function triggered on slot deletion failure |
|
|
| view | No | Specifies the layout of the booker atom into column, week, or month view |
|
|
| metadata | No | Used to pass custom metadata values into the booker. Metadata should be an object eg: `{ bookingSource: "website", userRole: "admin" }` |
|
|
| bannerUrl | No | Adds custom banner to the booker atom |
|
|
| onBookerStateChange | No | Callback function that is triggered when the state of the booker atom changes. |
|
|
| allowUpdatingUrlParams | No | Boolean indicating if the URL parameters should be updated, defaults to false. |
|
|
| confirmButtonDisabled | No | Boolean indicating if the submit button should be disabled, defaults to false. |
|
|
| timeZones | No | Array of valid IANA timezones to be used in the booker. Eg. ["Asia/Kolkata", "Europe/London"] |
|
|
| onTimeslotsLoaded | No | Callback function triggered once the available timeslots have been fetched. |
|
|
| roundRobinHideOrgAndTeam | No | Boolean indicating if the organization and team should be hidden in the booker atom sidebar for round robin scheduling type, defaults to false. |
|
|
| showNoAvailabilityDialog | No | Boolean indicating if the no availability dialog should be shown, defaults to true. |
|
|
| silentlyHandleCalendarFailures | No | Boolean when true the booker still displays slots when the third party calendars credentials are invalid or expired, Booker may show stale availability when enabled |
|
|
| hideEventMetadata | No | Boolean that controls the visibility of the event metadata sidebar. When `true`, hides the left sidebar containing event details like title, description, duration, and host information. Defaults to `false`. |
|
|
| defaultPhoneCountry | No | Sets the default country code for phone number inputs in the booking form. Accepts ISO 3166-1 alpha-2 country codes (e.g., `"us"`, `"gb"`, `"in"`, `"ee"`). When set, phone inputs will default to the specified country's dialing code. |
|
|
|
|
## Styling
|
|
|
|
Booker atom accepts custom styles via the `customClassNames` prop. This prop is an object that contains root level styles and nested objects for styling different parts of the booker component. Each nested object groups related styles for a specific section of the booker (e.g., eventMeta, datePicker, availableTimeSlots, etc).
|
|
|
|
Here is an example booker with root level style `bookerContainer` and nested object `datePickerCustomClassNames` with `datePickerDatesActive` style:
|
|
|
|
```js
|
|
import { Booker } from "@calcom/atoms";
|
|
|
|
export default function Booker( props : BookerProps ) {
|
|
return (
|
|
<>
|
|
<Booker
|
|
...
|
|
customClassNames={{
|
|
bookerContainer: "bg-[#F5F2FE]! [&_button:!rounded-full] border-subtle border",
|
|
datePickerCustomClassNames: {
|
|
datePickerDatesActive: "bg-[#D7CEF5]!",
|
|
},
|
|
}}
|
|
/>
|
|
</>
|
|
)
|
|
}
|
|
```
|
|
|
|
Below is a list of **customClassNames** properties grouped by their parent objects:
|
|
|
|
### Root Level Styles
|
|
|
|
| Property | Description |
|
|
| :-------------- | :------------------------------------------- |
|
|
| bookerContainer | Adds styling to the whole of the booker atom |
|
|
|
|
### Event Meta Styles (`eventMetaCustomClassNames`)
|
|
|
|
| Property | Description |
|
|
| :---------------------- | :---------------------------------------------------------------- |
|
|
| eventMetaContainer | Styles the event meta component containing details about an event |
|
|
| eventMetaTitle | Adds styles to the event meta title |
|
|
| eventMetaTimezoneSelect | Adds styles to the event meta timezone selector |
|
|
|
|
### Date Picker Styles (`datePickerCustomClassNames`)
|
|
|
|
| Property | Description |
|
|
| :-------------------- | :------------------------------------------- |
|
|
| datePickerContainer | Adds styling to the date picker |
|
|
| datePickerTitle | Styles the date picker title |
|
|
| datePickerDays | Adds styling to all days in the date picker |
|
|
| datePickerDate | Adds styling to all dates in the date picker |
|
|
| datePickerDatesActive | Styles only the dates with available slots |
|
|
| datePickerToggle | Styles the left and right toggle buttons |
|
|
|
|
### Available Time Slots Styles (`availableTimeSlotsCustomClassNames`)
|
|
|
|
| Property | Description |
|
|
| :--------------------------------- | :------------------------------------------------- |
|
|
| availableTimeSlotsContainer | Adds styling to the available time slots component |
|
|
| availableTimeSlotsHeaderContainer | Styles only the header container |
|
|
| availableTimeSlotsTitle | Adds styles to the title |
|
|
| availableTimeSlotsTimeFormatToggle | Adds styles to the format toggle buttons |
|
|
| availableTimes | Styles all the available times container |
|
|
|
|
### Confirmation Step Styles (`confirmStep`)
|
|
|
|
| Property | Description |
|
|
| :------------ | :-------------------------------------------- |
|
|
| confirmButton | Styles the confirm button in the booking form |
|
|
| backButton | Styles the back button in the booking form |
|
|
|
|
Here is an example with more custom styles:
|
|
|
|
```js
|
|
import { Booker } from "@calcom/atoms";
|
|
|
|
export default function Booker( props : BookerProps ) {
|
|
return (
|
|
<>
|
|
<Booker
|
|
...
|
|
customClassNames={{
|
|
bookerContainer: "bg-[#F5F2FE]! [&_button:!rounded-full] border-subtle border",
|
|
datePickerCustomClassNames: {
|
|
datePickerDatesActive: "bg-[#D7CEF5]!",
|
|
},
|
|
eventMetaCustomClassNames: {
|
|
eventMetaTitle: "text-[#7151DC]",
|
|
},
|
|
availableTimeSlotsCustomClassNames: {
|
|
availableTimeSlotsHeaderContainer: "bg-[#F5F2FE]!",
|
|
availableTimes: "bg-[#D7CEF5]!",
|
|
},
|
|
confirmStep: {
|
|
confirmButton: "bg-purple-700!",
|
|
backButton: "text-purple-700 hover:bg-purple-700! hover:text-white!"
|
|
}
|
|
}}
|
|
/>
|
|
</>
|
|
)
|
|
}
|
|
```
|
|
|
|
## Rescheduling a booking
|
|
|
|
The booker atom also supports rescheduling a booking. To reschedule a booking, you need to pass in the `rescheduleUid` prop to the booker atom along with the other necessary props. This will allow the booker to display the reschedule form and handle the rescheduling process. The `rescheduleUid` is the booking uid you get when you create a booking.
|
|
|
|
Here is an example of how to use the booker atom for rescheduling an individual event:
|
|
|
|
```js
|
|
import { Booker } from "@calcom/atoms";
|
|
|
|
export default function Booker( props : BookerProps ) {
|
|
return (
|
|
<>
|
|
<Booker
|
|
eventSlug={props.eventTypeSlug}
|
|
username={props.calUsername}
|
|
// rescheduleUid is the booking uid you get when you create a booking
|
|
// it is only required when rescheduling a booking
|
|
rescheduleUid={props.rescheduleUid}
|
|
onCreateBookingSuccess={() => {
|
|
console.log("Booking rescheduled successfully!");
|
|
}}
|
|
/>
|
|
</>
|
|
)
|
|
}
|
|
```
|
|
|
|
For team events, you need to pass isTeamEvent and teamId prop to the booker along with the other necessary props. This will allow the booker to display the reschedule form and handle the rescheduling process. The `teamId` is the team id you get when you create a team event.
|
|
|
|
Here is an example of how to use the booker atom for rescheduling a team event:
|
|
|
|
```js
|
|
import { Booker } from "@calcom/atoms";
|
|
|
|
export default function Booker( props : BookerProps ) {
|
|
return (
|
|
<>
|
|
<Booker
|
|
eventSlug={props.eventTypeSlug}
|
|
// rescheduleUid is the booking uid you get when you create a booking
|
|
// it is only required when rescheduling a booking
|
|
rescheduleUid={props.rescheduleUid}
|
|
isTeamEvent={true}
|
|
teamId={props.teamId}
|
|
onCreateBookingSuccess={() => {
|
|
console.log("Booking rescheduled successfully!");
|
|
}}
|
|
/>
|
|
</>
|
|
)
|
|
}
|
|
```
|