CAL-1623 CAL-1620: Improve animation for booker, and push mini calendar down in fullscreen views (#8773)

* CAL-1623 CAL-1620: Improve animation for booker, and push mini calendar down in fullscreen views

* Updated yarn.lock
This commit is contained in:
Jeroen Reumkens 2023-05-10 10:26:59 +02:00 committed by GitHub
parent ec3a3268c9
commit cc3be0a6ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 91 additions and 113 deletions

View File

@ -19,7 +19,7 @@ import { EventMeta } from "./components/EventMeta";
import { LargeCalendar } from "./components/LargeCalendar";
import { LargeViewHeader } from "./components/LargeViewHeader";
import { BookerSection } from "./components/Section";
import { fadeInLeft, resizeAnimationConfig } from "./config";
import { fadeInLeft, useBookerResizeAnimation } from "./config";
import { useBookerStore, useInitializeBookerStore } from "./store";
import type { BookerLayout, BookerProps } from "./types";
import { useEvent } from "./utils/event";
@ -56,6 +56,8 @@ const BookerComponent = ({ username, eventSlug, month, rescheduleBooking }: Book
const extraDays = layout === "large_timeslots" ? (isTablet ? 2 : 4) : 0;
const onLayoutToggle = useCallback((newLayout: BookerLayout) => setLayout(newLayout), [setLayout]);
const animationScope = useBookerResizeAnimation(layout, bookerState);
useBrandColors({
brandColor: event.data?.profile.brandColor,
darkBrandColor: event.data?.profile.darkBrandColor,
@ -124,24 +126,21 @@ const BookerComponent = ({ username, eventSlug, month, rescheduleBooking }: Book
)}
<div className="flex h-full w-full flex-col items-center">
<div
style={resizeAnimationConfig[layout]?.[bookerState] || resizeAnimationConfig[layout].default}
ref={animationScope}
className={classNames(
// Size settings are abstracted on their own lines purely for readbility.
// General sizes:
"[--booker-main-width:480px] [--booker-timeslots-width:240px] lg:[--booker-timeslots-width:280px]",
"bg-muted grid max-w-full auto-rows-max items-start overflow-clip dark:[color-scheme:dark] md:flex-row",
layout === "small_calendar" &&
"w-[calc(var(--booker-meta-width)+var(--booker-main-width))] [--booker-meta-width:240px] lg:[--booker-meta-width:280px]",
// Sizes for fullscreen layouts:
layout === "small_calendar" && "[--booker-meta-width:240px] lg:[--booker-meta-width:280px]",
layout !== "small_calendar" && "[--booker-meta-width:340px] lg:[--booker-meta-width:424px]",
// Other styles
layout === "small_calendar" && "border-subtle min-h-[450px] rounded-md border",
layout !== "small_calendar" && "h-auto min-h-screen w-screen",
"transition-[width,max-width] duration-300"
"bg-muted grid max-w-full auto-rows-fr items-start overflow-clip dark:[color-scheme:dark] sm:transition-[width] sm:duration-300 sm:motion-reduce:transition-none md:flex-row",
layout === "small_calendar" && "border-subtle rounded-md border"
)}>
<AnimatePresence>
<StickyOnDesktop key="meta" className="relative z-10">
<BookerSection area="meta" className="max-w-screen w-full md:w-[var(--booker-meta-width)]">
<StickyOnDesktop key="meta" className="relative z-10 flex min-h-full">
<BookerSection
area="meta"
className="max-w-screen flex w-full flex-col md:w-[var(--booker-meta-width)]">
<EventMeta />
{layout !== "small_calendar" && !(layout === "mobile" && bookerState === "booking") && (
<div className=" mt-auto p-5">

View File

@ -1,3 +1,7 @@
import { cubicBezier, useAnimate } from "framer-motion";
import { useReducedMotion } from "framer-motion";
import { useEffect } from "react";
import type { BookerLayout, BookerState } from "./types";
// Framer motion fade in animation configs.
@ -43,6 +47,7 @@ export const resizeAnimationConfig: ResizeAnimationConfig = {
mobile: {
default: {
width: "100%",
minHeight: "0px",
gridTemplateAreas: `
"meta"
"main"
@ -54,28 +59,86 @@ export const resizeAnimationConfig: ResizeAnimationConfig = {
small_calendar: {
default: {
width: "calc(var(--booker-meta-width) + var(--booker-main-width))",
minHeight: "450px",
height: "auto",
gridTemplateAreas: `"meta main"`,
gridTemplateColumns: "var(--booker-meta-width) var(--booker-main-width)",
},
selecting_time: {
width: "100%",
maxWidth: "calc(var(--booker-meta-width) + var(--booker-main-width) + var(--booker-timeslots-width))",
width: "calc(var(--booker-meta-width) + var(--booker-main-width) + var(--booker-timeslots-width))",
minHeight: "450px",
height: "auto",
gridTemplateAreas: `"meta main timeslots"`,
gridTemplateColumns: "var(--booker-meta-width) 1fr var(--booker-timeslots-width)",
},
},
large_calendar: {
default: {
width: "100%",
width: "100vw",
height: "100vh",
gridTemplateAreas: `"meta main"`,
gridTemplateColumns: "var(--booker-meta-width) 1fr",
},
},
large_timeslots: {
default: {
width: "100%",
width: "100vw",
height: "100vh",
gridTemplateAreas: `"meta main"`,
gridTemplateColumns: "var(--booker-meta-width) 1fr",
},
},
};
/**
* This hook returns a ref that should be set on the booker element.
* Based on that ref this hook animates the size of the booker element with framer motion.
* It also takes into account the prefers-reduced-motion setting, to not animate when that's set.
*/
export const useBookerResizeAnimation = (layout: BookerLayout, state: BookerState) => {
const prefersReducedMotion = useReducedMotion();
const [animationScope, animate] = useAnimate();
useEffect(() => {
const animationConfig = resizeAnimationConfig[layout][state] || resizeAnimationConfig[layout].default;
const animatedProperties = {
height: animationConfig?.height || "auto",
};
const nonAnimatedProperties = {
// Width is animated by the css class instead of via framer motion,
// because css is better at animating the calcs, framer motion might
// make some mistakes in that.
width: animationConfig?.width || "auto",
gridTemplateAreas: animationConfig?.gridTemplateAreas,
gridTemplateColumns: animationConfig?.gridTemplateColumns,
minHeight: animationConfig?.minHeight,
};
// We don't animate if users has set prefers-reduced-motion,
// or when the layout is mobile.
if (prefersReducedMotion || layout === "mobile") {
animate(
animationScope.current,
{
...animatedProperties,
...nonAnimatedProperties,
},
{
duration: 0,
}
);
} else {
animate(animationScope.current, nonAnimatedProperties, {
duration: 0,
});
animate(animationScope.current, animatedProperties, {
duration: 0.5,
ease: cubicBezier(0.4, 0, 0.2, 1),
});
}
}, [animate, animationScope, layout, prefersReducedMotion, state]);
return animationScope;
};

View File

@ -12,7 +12,7 @@
"@calcom/ui": "*",
"@lexical/react": "^0.5.0",
"dompurify": "^2.4.1",
"framer-motion": "^10.12.3",
"framer-motion": "^10.12.8",
"lexical": "^0.5.0",
"react-sticky-box": "^2.0.4",
"zustand": "^4.3.2"

108
yarn.lock
View File

@ -134,25 +134,6 @@ __metadata:
languageName: node
linkType: hard
"@auth/core@npm:^0.1.4":
version: 0.1.4
resolution: "@auth/core@npm:0.1.4"
dependencies:
"@panva/hkdf": 1.0.2
cookie: 0.5.0
jose: 4.11.1
oauth4webapi: 2.0.5
preact: 10.11.3
preact-render-to-string: 5.2.3
peerDependencies:
nodemailer: 6.8.0
peerDependenciesMeta:
nodemailer:
optional: true
checksum: 64854404ea1883e0deb5535b34bed95cd43fc85094aeaf4f15a79e14045020eb944f844defe857edfc8528a0a024be89cbb2a3069dedef0e9217a74ca6c3eb79
languageName: node
linkType: hard
"@aws-crypto/ie11-detection@npm:^3.0.0":
version: 3.0.0
resolution: "@aws-crypto/ie11-detection@npm:3.0.0"
@ -4015,39 +3996,6 @@ __metadata:
languageName: unknown
linkType: soft
"@calcom/auth@workspace:apps/auth":
version: 0.0.0-use.local
resolution: "@calcom/auth@workspace:apps/auth"
dependencies:
"@auth/core": ^0.1.4
"@calcom/app-store": "*"
"@calcom/app-store-cli": "*"
"@calcom/config": "*"
"@calcom/core": "*"
"@calcom/dayjs": "*"
"@calcom/embed-core": "workspace:*"
"@calcom/embed-react": "workspace:*"
"@calcom/embed-snippet": "workspace:*"
"@calcom/features": "*"
"@calcom/lib": "*"
"@calcom/prisma": "*"
"@calcom/trpc": "*"
"@calcom/tsconfig": "*"
"@calcom/types": "*"
"@calcom/ui": "*"
"@types/node": 16.9.1
"@types/react": 18.0.26
"@types/react-dom": 18.0.9
eslint: ^8.34.0
eslint-config-next: ^13.2.1
next: ^13.2.1
next-auth: ^4.20.1
react: ^18.2.0
react-dom: ^18.2.0
typescript: ^4.9.4
languageName: unknown
linkType: soft
"@calcom/caldavcalendar@workspace:packages/app-store/caldavcalendar":
version: 0.0.0-use.local
resolution: "@calcom/caldavcalendar@workspace:packages/app-store/caldavcalendar"
@ -4387,7 +4335,7 @@ __metadata:
"@lexical/react": ^0.5.0
"@testing-library/react-hooks": ^8.0.1
dompurify: ^2.4.1
framer-motion: ^10.12.3
framer-motion: ^10.12.8
lexical: ^0.5.0
mockdate: ^3.0.5
react-sticky-box: ^2.0.4
@ -8388,13 +8336,6 @@ __metadata:
languageName: node
linkType: hard
"@panva/hkdf@npm:1.0.2":
version: 1.0.2
resolution: "@panva/hkdf@npm:1.0.2"
checksum: 75183b4d5ea816ef516dcea70985c610683579a9e2ac540c2d59b9a3ed27eedaff830a43a1c43c1683556a457c92ac66e09109ee995ab173090e4042c4c4bb03
languageName: node
linkType: hard
"@panva/hkdf@npm:^1.0.2":
version: 1.0.4
resolution: "@panva/hkdf@npm:1.0.4"
@ -22743,9 +22684,9 @@ __metadata:
languageName: node
linkType: hard
"framer-motion@npm:^10.12.3":
version: 10.12.3
resolution: "framer-motion@npm:10.12.3"
"framer-motion@npm:^10.12.8":
version: 10.12.8
resolution: "framer-motion@npm:10.12.8"
dependencies:
"@emotion/is-prop-valid": ^0.8.2
tslib: ^2.4.0
@ -22760,7 +22701,7 @@ __metadata:
optional: true
react-dom:
optional: true
checksum: c292da47b5bcb313e3db2ffe19e61b3c76bf59f4a45dc72f62a3d9b33f58533d420aced47d5e9eb06be20be97651c937ae91aebb93d8bad6d0412c2768715956
checksum: 2e21e06eed99967e816c27101cc4d438048d9c7c36d318acfdb4f3d14eee593b022696303a9416032caf735f6817cdc6b287a7ed004b21d07f67c7cbe534edfe
languageName: node
linkType: hard
@ -26594,13 +26535,6 @@ __metadata:
languageName: node
linkType: hard
"jose@npm:4.11.1":
version: 4.11.1
resolution: "jose@npm:4.11.1"
checksum: cd15cba258d0fd20f6168631ce2e94fda8442df80e43c1033c523915cecdf390a1cc8efe0eab0c2d65935ca973d791c668aea80724d2aa9c2879d4e70f3081d7
languageName: node
linkType: hard
"jose@npm:4.12.0":
version: 4.12.0
resolution: "jose@npm:4.12.0"
@ -30703,13 +30637,6 @@ __metadata:
languageName: node
linkType: hard
"oauth4webapi@npm:2.0.5":
version: 2.0.5
resolution: "oauth4webapi@npm:2.0.5"
checksum: 32d0cb7b1cca42d51dfb88075ca2d69fe33172a807e8ea50e317d17cab3bc80588ab8ebcb7eb4600c371a70af4674595b4b341daf6f3a655f1efa1ab715bb6c9
languageName: node
linkType: hard
"oauth@npm:^0.9.15":
version: 0.9.15
resolution: "oauth@npm:0.9.15"
@ -32400,17 +32327,6 @@ __metadata:
languageName: node
linkType: hard
"preact-render-to-string@npm:5.2.3":
version: 5.2.3
resolution: "preact-render-to-string@npm:5.2.3"
dependencies:
pretty-format: ^3.8.0
peerDependencies:
preact: ">=10"
checksum: 6e46288d8956adde35b9fe3a21aecd9dea29751b40f0f155dea62f3896f27cb8614d457b32f48d33909d2da81135afcca6c55077520feacd7d15164d1371fb44
languageName: node
linkType: hard
"preact-render-to-string@npm:^5.1.19":
version: 5.2.6
resolution: "preact-render-to-string@npm:5.2.6"
@ -32422,13 +32338,6 @@ __metadata:
languageName: node
linkType: hard
"preact@npm:10.11.3, preact@npm:^10.6.3":
version: 10.11.3
resolution: "preact@npm:10.11.3"
checksum: 9387115aa0581e8226309e6456e9856f17dfc0e3d3e63f774de80f3d462a882ba7c60914c05942cb51d51e23e120dcfe904b8d392d46f29ad15802941fe7a367
languageName: node
linkType: hard
"preact@npm:10.4.1":
version: 10.4.1
resolution: "preact@npm:10.4.1"
@ -32443,6 +32352,13 @@ __metadata:
languageName: node
linkType: hard
"preact@npm:^10.6.3":
version: 10.11.3
resolution: "preact@npm:10.11.3"
checksum: 9387115aa0581e8226309e6456e9856f17dfc0e3d3e63f774de80f3d462a882ba7c60914c05942cb51d51e23e120dcfe904b8d392d46f29ad15802941fe7a367
languageName: node
linkType: hard
"prelude-ls@npm:^1.2.1":
version: 1.2.1
resolution: "prelude-ls@npm:1.2.1"