* chore: add new view for two step slot selection for embed * fix: make sure two step slot selection is false by default * chore: update embed playground to showcase two step slot selection * chore: add tests * chore: update embed snippet generator code to include two step slot selection * chore: update docs * fix: back button styling * chore: implement feedback from cubic * fix: add missing isEnableTwoStepSlotSelectionVisible properties to test mock store Co-Authored-By: unknown <> * chore: implement PR feedback * chore: update slot selection modal * chore: add prop to hide available times header * fix: scope two-step slot selection visibility to mobile only Restores the isMobile check in the timeslot visibility guard to ensure desktop embeds continue to show the booking UI when two-step slot selection is enabled. The feature should only hide the timeslot list on mobile devices. Addresses Cubic AI review feedback (confidence 9/10). Co-Authored-By: unknown <> * fixup: use translations for loading instead of actual word * fix: type check * fix: add window.matchMedia mock for jsdom test environment Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com> * fix: add window.matchMedia mock to packages/testing/src/setupVitest.ts Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com> * fix: unit tests failing * add a width style to the two-step slot selection embed container. * refactor: rename enableTwoStepSlotSelection to useSlotsViewOnSmallScreen - Rename external-facing embed config option from enableTwoStepSlotSelection to useSlotsViewOnSmallScreen - Update URL parameter parsing in embed-iframe.ts - Update type definitions in types.ts and index.d.ts - Update internal variable names to slotsViewOnSmallScreen for consistency - Update documentation, playground examples, and tests Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com> * Add config to prefill all booking fields so that slot has confirm button along with it * chore: implement PR feedback * fix: move twoStepSlotSelection embed outside misc-embeds div to fix e2e test The e2e test was failing because the misc-embeds div content was intercepting pointer events on mobile viewport. This follows the same pattern used for skeletonDemo - the embed is now outside misc-embeds and the div is hidden when testing this namespace. Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com> * fix: prevent pointer event interception in twoStepSlotSelection embed Hide heading and note elements and set pointer-events: none on container elements while keeping pointer-events: auto on the iframe container. This prevents the container from intercepting clicks on the iframe during mobile viewport e2e tests. Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com> * fix: hide all non-essential content for twoStepSlotSelection e2e test Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com> * fix: disable pointer-events on body for twoStepSlotSelection e2e test Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com> * fix: remove pointer-events: auto on container to let clicks pass through to iframe Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com> * fix: explicitly set pointer-events: none on container and inline-embed-container Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com> * fix: also set pointer-events: none on html element to prevent interception Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com> * fix: make .place div fill viewport for twoStepSlotSelection e2e test Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com> * fix: failing embed tests * fixup * fixup fixup * fix: failing tests * fix: update checks for verifying prefilled date --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: Peer Richelsen <peeroke@gmail.com> Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
121 lines
3.4 KiB
TypeScript
121 lines
3.4 KiB
TypeScript
/**
|
|
* @fileoverview This file is an example file and tells how to use the Cal component in a React application. This is also used by playwright e2e
|
|
*/
|
|
import * as React from "react";
|
|
import { useEffect } from "react";
|
|
import { useState } from "react";
|
|
import ReactDom from "react-dom";
|
|
|
|
// Because we don't import from @calcom/embed-react, this file isn't able to test if the build is successful or not and thus npm package would work or not correctly.
|
|
// There are tests in test/built which verify that the types from built package are correctly generated and exported correctly.
|
|
import Cal, { getCalApi, type EmbedEvent } from "./src/index";
|
|
|
|
const api = getCalApi({
|
|
namespace: "inline",
|
|
});
|
|
|
|
function App() {
|
|
const [, setLoaded] = useState(false);
|
|
useEffect(() => {
|
|
// Simulate state change causing config object to change, causing rerender of Cal
|
|
setTimeout(setLoaded.bind(true), 1000);
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
const callback = (event: any) => {
|
|
console.log(event.detail);
|
|
};
|
|
api.then((api) => {
|
|
api("on", {
|
|
action: "*",
|
|
callback,
|
|
});
|
|
|
|
api("ui", {
|
|
cssVarsPerTheme: {
|
|
light: {
|
|
"cal-border-booker": "red",
|
|
"cal-border-booker-width": "20px",
|
|
},
|
|
dark: {
|
|
"cal-border-booker": "red",
|
|
"cal-border-booker-width": "5px",
|
|
},
|
|
},
|
|
});
|
|
});
|
|
|
|
return () => {
|
|
api.then((api) => {
|
|
api("off", {
|
|
action: "*",
|
|
callback,
|
|
});
|
|
|
|
const bookerReadyCallback = (e: EmbedEvent<"bookerReady">) => {
|
|
const data = e.detail.data;
|
|
console.log("bookerReady", {
|
|
eventId: data.eventId,
|
|
eventSlug: data.eventSlug,
|
|
});
|
|
|
|
api("off", {
|
|
action: "bookerReady",
|
|
callback: bookerReadyCallback,
|
|
});
|
|
};
|
|
|
|
api("on", {
|
|
action: "bookerReady",
|
|
callback: bookerReadyCallback,
|
|
});
|
|
|
|
// Also, validates the type of e.detail.data as TS runs on this file
|
|
const bookingSuccessfulV2Callback = (
|
|
e: EmbedEvent<"bookingSuccessfulV2">
|
|
) => {
|
|
const data = e.detail.data;
|
|
console.log("bookingSuccessfulV2", {
|
|
endTime: data.endTime,
|
|
startTime: data.startTime,
|
|
title: data.title,
|
|
});
|
|
|
|
// Remove the event listener after it is fired once as I don't need it.
|
|
api("off", {
|
|
action: "bookingSuccessfulV2",
|
|
callback: bookingSuccessfulV2Callback,
|
|
});
|
|
};
|
|
|
|
api("on", {
|
|
action: "bookingSuccessfulV2",
|
|
callback: bookingSuccessfulV2Callback,
|
|
});
|
|
});
|
|
};
|
|
}, []);
|
|
return (
|
|
<>
|
|
<h1>
|
|
There is <code>Cal</code> component below me
|
|
</h1>
|
|
<Cal
|
|
calOrigin="http://localhost:3000"
|
|
embedJsUrl="//localhost:3000/embed/embed.js"
|
|
namespace="inline"
|
|
style={{ width: "100%", height: "100%", overflow: "scroll" }}
|
|
calLink="pro"
|
|
config={{
|
|
name: "John Doe",
|
|
email: "johndoe@gmail.com",
|
|
notes: "Test Meeting",
|
|
guests: ["janedoe@gmail.com"],
|
|
theme: "dark",
|
|
"cal.embed.pageType": "user.event.booking.slots",
|
|
useSlotsViewOnSmallScreen: "true",
|
|
}}
|
|
/>
|
|
</>
|
|
);
|
|
}
|
|
ReactDom.render(<App />, document.getElementById("root"));
|