mirror of
https://github.com/lukevella/rallly.git
synced 2025-05-21 12:56:21 +02:00
⚡️ Lazy load animation library to help reduce bundle size (#502)
This commit is contained in:
parent
c2c000f770
commit
696cd44ba1
14 changed files with 115 additions and 83 deletions
|
@ -1,4 +1,4 @@
|
||||||
import { AnimatePresence, motion } from "framer-motion";
|
import { AnimatePresence, m } from "framer-motion";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { useTranslation } from "next-i18next";
|
import { useTranslation } from "next-i18next";
|
||||||
import posthog from "posthog-js";
|
import posthog from "posthog-js";
|
||||||
|
@ -97,7 +97,7 @@ export const AdminControls = (props: { children?: React.ReactNode }) => {
|
||||||
</div>
|
</div>
|
||||||
<AnimatePresence initial={false}>
|
<AnimatePresence initial={false}>
|
||||||
{isSharingVisible ? (
|
{isSharingVisible ? (
|
||||||
<motion.div
|
<m.div
|
||||||
initial={{
|
initial={{
|
||||||
opacity: 0,
|
opacity: 0,
|
||||||
scale: 0.8,
|
scale: 0.8,
|
||||||
|
@ -122,13 +122,13 @@ export const AdminControls = (props: { children?: React.ReactNode }) => {
|
||||||
setIsSharingVisible(false);
|
setIsSharingVisible(false);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</motion.div>
|
</m.div>
|
||||||
) : null}
|
) : null}
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
<motion.div className="relative z-10 space-y-4" layout="position">
|
<m.div className="relative z-10 space-y-4" layout="position">
|
||||||
{poll.verified === false ? <UnverifiedPollNotice /> : null}
|
{poll.verified === false ? <UnverifiedPollNotice /> : null}
|
||||||
{props.children}
|
{props.children}
|
||||||
</motion.div>
|
</m.div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { AnimatePresence, motion } from "framer-motion";
|
import { AnimatePresence, m } from "framer-motion";
|
||||||
import Cookies from "js-cookie";
|
import Cookies from "js-cookie";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
@ -14,7 +14,7 @@ const CookieConsentPopover: React.VoidFunctionComponent = () => {
|
||||||
return ReactDOM.createPortal(
|
return ReactDOM.createPortal(
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
{visible ? (
|
{visible ? (
|
||||||
<motion.div
|
<m.div
|
||||||
variants={{
|
variants={{
|
||||||
enter: {
|
enter: {
|
||||||
opacity: 1,
|
opacity: 1,
|
||||||
|
@ -54,7 +54,7 @@ const CookieConsentPopover: React.VoidFunctionComponent = () => {
|
||||||
OK
|
OK
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</m.div>
|
||||||
) : null}
|
) : null}
|
||||||
</AnimatePresence>,
|
</AnimatePresence>,
|
||||||
getPortal(),
|
getPortal(),
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* eslint-disable @next/next/no-html-link-for-pages */
|
/* eslint-disable @next/next/no-html-link-for-pages */
|
||||||
import { motion } from "framer-motion";
|
import { m } from "framer-motion";
|
||||||
import { Trans, useTranslation } from "next-i18next";
|
import { Trans, useTranslation } from "next-i18next";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
|
||||||
|
@ -46,13 +46,13 @@ const Hero: React.VoidFunctionComponent = () => {
|
||||||
<UserAvatarProvider seed="mock" names={names}>
|
<UserAvatarProvider seed="mock" names={names}>
|
||||||
<DayjsProvider>
|
<DayjsProvider>
|
||||||
<div className="relative inline-block">
|
<div className="relative inline-block">
|
||||||
<motion.div
|
<m.div
|
||||||
className="absolute z-20 h-full rounded-2xl border-4 border-primary-500 bg-primary-200/10 shadow-md"
|
className="absolute z-20 h-full rounded-2xl border-4 border-primary-500 bg-primary-200/10 shadow-md"
|
||||||
initial={{ opacity: 0, width: 100, scale: 1.1, x: 480 }}
|
initial={{ opacity: 0, width: 100, scale: 1.1, x: 480 }}
|
||||||
animate={{ opacity: 1, x: 381 }}
|
animate={{ opacity: 1, x: 381 }}
|
||||||
transition={{ type: "spring", delay: 1 }}
|
transition={{ type: "spring", delay: 1 }}
|
||||||
/>
|
/>
|
||||||
<motion.div
|
<m.div
|
||||||
className="absolute z-20 rounded-full bg-primary-500 py-1 px-3 text-sm text-slate-100"
|
className="absolute z-20 rounded-full bg-primary-500 py-1 px-3 text-sm text-slate-100"
|
||||||
initial={{
|
initial={{
|
||||||
opacity: 0,
|
opacity: 0,
|
||||||
|
@ -65,15 +65,15 @@ const Hero: React.VoidFunctionComponent = () => {
|
||||||
>
|
>
|
||||||
{t("perfect")} 🤩
|
{t("perfect")} 🤩
|
||||||
<ScribbleArrow className="absolute -right-8 top-3 text-slate-400" />
|
<ScribbleArrow className="absolute -right-8 top-3 text-slate-400" />
|
||||||
</motion.div>
|
</m.div>
|
||||||
<motion.div
|
<m.div
|
||||||
className="rounded-lg"
|
className="rounded-lg"
|
||||||
transition={{ type: "spring", delay: 0.5 }}
|
transition={{ type: "spring", delay: 0.5 }}
|
||||||
initial={{ opacity: 0, translateY: -100 }}
|
initial={{ opacity: 0, translateY: -100 }}
|
||||||
animate={{ opacity: 1, translateY: 0 }}
|
animate={{ opacity: 1, translateY: 0 }}
|
||||||
>
|
>
|
||||||
<PollDemo />
|
<PollDemo />
|
||||||
</motion.div>
|
</m.div>
|
||||||
</div>
|
</div>
|
||||||
</DayjsProvider>
|
</DayjsProvider>
|
||||||
</UserAvatarProvider>
|
</UserAvatarProvider>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
|
import { domAnimation, LazyMotion } from "framer-motion";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { Trans, useTranslation } from "next-i18next";
|
import { Trans, useTranslation } from "next-i18next";
|
||||||
|
@ -62,33 +63,35 @@ const PageLayout: React.VoidFunctionComponent<PageLayoutProps> = ({
|
||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation("homepage");
|
const { t } = useTranslation("homepage");
|
||||||
return (
|
return (
|
||||||
<div className="bg-pattern min-h-full overflow-x-hidden">
|
<LazyMotion features={domAnimation}>
|
||||||
<div className="mx-auto flex max-w-7xl items-center py-8 px-8">
|
<div className="bg-pattern min-h-full overflow-x-hidden">
|
||||||
<div className="grow">
|
<div className="mx-auto flex max-w-7xl items-center py-8 px-8">
|
||||||
<div className="relative inline-block">
|
<div className="grow">
|
||||||
<Link className="inline-block rounded" href="/">
|
<div className="relative inline-block">
|
||||||
<Logo className="w-40 text-primary-500" alt="Rallly" />
|
<Link className="inline-block rounded" href="/">
|
||||||
</Link>
|
<Logo className="w-40 text-primary-500" alt="Rallly" />
|
||||||
<span className="absolute -bottom-6 right-0 text-sm text-slate-400 transition-colors">
|
</Link>
|
||||||
<Trans t={t} i18nKey="3Ls" components={{ e: <em /> }} />
|
<span className="absolute -bottom-6 right-0 text-sm text-slate-400 transition-colors">
|
||||||
</span>
|
<Trans t={t} i18nKey="3Ls" components={{ e: <em /> }} />
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<Menu className="hidden items-center space-x-8 sm:flex" />
|
||||||
|
<Popover>
|
||||||
|
<PopoverTrigger asChild={true}>
|
||||||
|
<button className="text-gray-400 transition-colors hover:text-primary-500 hover:no-underline hover:underline-offset-2 sm:hidden">
|
||||||
|
<DotsVertical className="w-5" />
|
||||||
|
</button>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<PopoverContent align="end">
|
||||||
|
<Menu className="flex flex-col space-y-2 p-2" />
|
||||||
|
</PopoverContent>
|
||||||
|
</Popover>
|
||||||
</div>
|
</div>
|
||||||
<Menu className="hidden items-center space-x-8 sm:flex" />
|
<div className="md:min-h-[calc(100vh-460px)]">{children}</div>
|
||||||
<Popover>
|
<Footer />
|
||||||
<PopoverTrigger asChild={true}>
|
|
||||||
<button className="text-gray-400 transition-colors hover:text-primary-500 hover:no-underline hover:underline-offset-2 sm:hidden">
|
|
||||||
<DotsVertical className="w-5" />
|
|
||||||
</button>
|
|
||||||
</PopoverTrigger>
|
|
||||||
<PopoverContent align="end">
|
|
||||||
<Menu className="flex flex-col space-y-2 p-2" />
|
|
||||||
</PopoverContent>
|
|
||||||
</Popover>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="md:min-h-[calc(100vh-460px)]">{children}</div>
|
</LazyMotion>
|
||||||
<Footer />
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,42 @@
|
||||||
|
import { AnimatePresence, domAnimation, LazyMotion, m } from "framer-motion";
|
||||||
|
import { useRouter } from "next/router";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { DayjsProvider } from "@/utils/dayjs";
|
import { DayjsProvider } from "@/utils/dayjs";
|
||||||
|
|
||||||
import { NextPageWithLayout } from "../../types";
|
import { NextPageWithLayout } from "../../types";
|
||||||
|
import ModalProvider from "../modal/modal-provider";
|
||||||
import { UserProvider } from "../user-provider";
|
import { UserProvider } from "../user-provider";
|
||||||
import { MobileNavigation } from "./standard-layout/mobile-navigation";
|
import { MobileNavigation } from "./standard-layout/mobile-navigation";
|
||||||
|
|
||||||
const StandardLayout: React.VoidFunctionComponent<{
|
const StandardLayout: React.VoidFunctionComponent<{
|
||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
}> = ({ children, ...rest }) => {
|
}> = ({ children, ...rest }) => {
|
||||||
|
const router = useRouter();
|
||||||
return (
|
return (
|
||||||
<UserProvider>
|
<LazyMotion features={domAnimation}>
|
||||||
<DayjsProvider>
|
<UserProvider>
|
||||||
<div className={"bg-pattern relative min-h-full"} {...rest}>
|
<DayjsProvider>
|
||||||
<MobileNavigation />
|
<ModalProvider>
|
||||||
<div className="mx-auto max-w-4xl">{children}</div>
|
<div className={"bg-pattern relative min-h-full"} {...rest}>
|
||||||
</div>
|
<MobileNavigation />
|
||||||
</DayjsProvider>
|
<div className="mx-auto max-w-4xl">
|
||||||
</UserProvider>
|
<AnimatePresence initial={false} exitBeforeEnter={true}>
|
||||||
|
<m.div
|
||||||
|
key={router.asPath}
|
||||||
|
initial={{ opacity: 0, y: -50 }}
|
||||||
|
animate={{ opacity: 1, y: 0 }}
|
||||||
|
exit={{ opacity: 0, y: -50 }}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</m.div>
|
||||||
|
</AnimatePresence>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ModalProvider>
|
||||||
|
</DayjsProvider>
|
||||||
|
</UserProvider>
|
||||||
|
</LazyMotion>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Dialog } from "@headlessui/react";
|
import { Dialog } from "@headlessui/react";
|
||||||
import { AnimatePresence, motion } from "framer-motion";
|
import { AnimatePresence, m } from "framer-motion";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
|
||||||
import X from "@/components/icons/x.svg";
|
import X from "@/components/icons/x.svg";
|
||||||
|
@ -47,19 +47,19 @@ const Modal: React.VoidFunctionComponent<ModalProps> = ({
|
||||||
if (overlayClosable) onCancel?.();
|
if (overlayClosable) onCancel?.();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<motion.div
|
<m.div
|
||||||
transition={{ duration: 0.5 }}
|
transition={{ duration: 0.5 }}
|
||||||
className="flex min-h-screen items-center justify-center"
|
className="flex min-h-screen items-center justify-center"
|
||||||
>
|
>
|
||||||
<Dialog.Overlay
|
<Dialog.Overlay
|
||||||
as={motion.div}
|
as={m.div}
|
||||||
transition={{ duration: 0.5 }}
|
transition={{ duration: 0.5 }}
|
||||||
initial={{ opacity: 0 }}
|
initial={{ opacity: 0 }}
|
||||||
animate={{ opacity: 1 }}
|
animate={{ opacity: 1 }}
|
||||||
exit={{ opacity: 0 }}
|
exit={{ opacity: 0 }}
|
||||||
className="fixed inset-0 z-0 bg-slate-900/25"
|
className="fixed inset-0 z-0 bg-slate-900/25"
|
||||||
/>
|
/>
|
||||||
<motion.div
|
<m.div
|
||||||
transition={{ duration: 0.1 }}
|
transition={{ duration: 0.1 }}
|
||||||
initial={{ opacity: 0, scale: 0.9 }}
|
initial={{ opacity: 0, scale: 0.9 }}
|
||||||
animate={{ opacity: 1, scale: 1 }}
|
animate={{ opacity: 1, scale: 1 }}
|
||||||
|
@ -116,8 +116,8 @@ const Modal: React.VoidFunctionComponent<ModalProps> = ({
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</m.div>
|
||||||
</motion.div>
|
</m.div>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
) : null}
|
) : null}
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { AnimatePresence, motion } from "framer-motion";
|
import { AnimatePresence, m } from "framer-motion";
|
||||||
import { Trans, useTranslation } from "next-i18next";
|
import { Trans, useTranslation } from "next-i18next";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { useMeasure } from "react-use";
|
import { useMeasure } from "react-use";
|
||||||
|
@ -191,7 +191,7 @@ const Poll: React.VoidFunctionComponent = () => {
|
||||||
{shouldShowNewParticipantForm &&
|
{shouldShowNewParticipantForm &&
|
||||||
!poll.closed &&
|
!poll.closed &&
|
||||||
!editingParticipantId ? (
|
!editingParticipantId ? (
|
||||||
<motion.div
|
<m.div
|
||||||
variants={{
|
variants={{
|
||||||
hidden: { height: 0, y: -50, opacity: 0 },
|
hidden: { height: 0, y: -50, opacity: 0 },
|
||||||
visible: { height: "auto", y: 0, opacity: 1 },
|
visible: { height: "auto", y: 0, opacity: 1 },
|
||||||
|
@ -211,7 +211,7 @@ const Poll: React.VoidFunctionComponent = () => {
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</motion.div>
|
</m.div>
|
||||||
) : null}
|
) : null}
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
{participants.map((participant, i) => {
|
{participants.map((participant, i) => {
|
||||||
|
@ -247,7 +247,7 @@ const Poll: React.VoidFunctionComponent = () => {
|
||||||
</div>
|
</div>
|
||||||
<AnimatePresence initial={false}>
|
<AnimatePresence initial={false}>
|
||||||
{shouldShowNewParticipantForm || editingParticipantId ? (
|
{shouldShowNewParticipantForm || editingParticipantId ? (
|
||||||
<motion.div
|
<m.div
|
||||||
variants={{
|
variants={{
|
||||||
hidden: { height: 0, y: 30, opacity: 0 },
|
hidden: { height: 0, y: 30, opacity: 0 },
|
||||||
visible: { height: "auto", y: 0, opacity: 1 },
|
visible: { height: "auto", y: 0, opacity: 1 },
|
||||||
|
@ -281,7 +281,7 @@ const Poll: React.VoidFunctionComponent = () => {
|
||||||
{shouldShowNewParticipantForm ? t("continue") : t("save")}
|
{shouldShowNewParticipantForm ? t("continue") : t("save")}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</m.div>
|
||||||
) : null}
|
) : null}
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import { AnimatePresence, motion } from "framer-motion";
|
import { AnimatePresence, m } from "framer-motion";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { usePollContext } from "./poll-context";
|
import { usePollContext } from "./poll-context";
|
||||||
|
@ -16,7 +16,7 @@ const ControlledScrollArea: React.VoidFunctionComponent<{
|
||||||
style={{ width: availableSpace, maxWidth: availableSpace }}
|
style={{ width: availableSpace, maxWidth: availableSpace }}
|
||||||
>
|
>
|
||||||
<AnimatePresence initial={false}>
|
<AnimatePresence initial={false}>
|
||||||
<motion.div
|
<m.div
|
||||||
className="flex h-full"
|
className="flex h-full"
|
||||||
transition={{
|
transition={{
|
||||||
type: "spring",
|
type: "spring",
|
||||||
|
@ -26,7 +26,7 @@ const ControlledScrollArea: React.VoidFunctionComponent<{
|
||||||
animate={{ x: scrollPosition * -1 }}
|
animate={{ x: scrollPosition * -1 }}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</motion.div>
|
</m.div>
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Listbox } from "@headlessui/react";
|
import { Listbox } from "@headlessui/react";
|
||||||
import { AnimatePresence, motion } from "framer-motion";
|
import { AnimatePresence, m } from "framer-motion";
|
||||||
import { useTranslation } from "next-i18next";
|
import { useTranslation } from "next-i18next";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { FormProvider, useForm } from "react-hook-form";
|
import { FormProvider, useForm } from "react-hook-form";
|
||||||
|
@ -131,7 +131,7 @@ const MobilePoll: React.VoidFunctionComponent = () => {
|
||||||
<ChevronDown className="h-5 shrink-0" />
|
<ChevronDown className="h-5 shrink-0" />
|
||||||
</Listbox.Button>
|
</Listbox.Button>
|
||||||
<Listbox.Options
|
<Listbox.Options
|
||||||
as={motion.div}
|
as={m.div}
|
||||||
transition={{
|
transition={{
|
||||||
duration: 0.1,
|
duration: 0.1,
|
||||||
}}
|
}}
|
||||||
|
@ -257,7 +257,7 @@ const MobilePoll: React.VoidFunctionComponent = () => {
|
||||||
/>
|
/>
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
{isEditing ? (
|
{isEditing ? (
|
||||||
<motion.div
|
<m.div
|
||||||
variants={{
|
variants={{
|
||||||
hidden: { opacity: 0, y: -100, height: 0 },
|
hidden: { opacity: 0, y: -100, height: 0 },
|
||||||
visible: { opacity: 1, y: 0, height: "auto" },
|
visible: { opacity: 1, y: 0, height: "auto" },
|
||||||
|
@ -281,7 +281,7 @@ const MobilePoll: React.VoidFunctionComponent = () => {
|
||||||
{selectedParticipantId ? t("save") : t("continue")}
|
{selectedParticipantId ? t("save") : t("continue")}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</m.div>
|
||||||
) : null}
|
) : null}
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Participant, VoteType } from "@prisma/client";
|
import { Participant, VoteType } from "@prisma/client";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import { AnimatePresence, motion } from "framer-motion";
|
import { AnimatePresence, m } from "framer-motion";
|
||||||
import { useTranslation } from "next-i18next";
|
import { useTranslation } from "next-i18next";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ const CollapsibleContainer: React.VoidFunctionComponent<{
|
||||||
return (
|
return (
|
||||||
<AnimatePresence initial={false}>
|
<AnimatePresence initial={false}>
|
||||||
{expanded ? (
|
{expanded ? (
|
||||||
<motion.div
|
<m.div
|
||||||
variants={{
|
variants={{
|
||||||
collapsed: {
|
collapsed: {
|
||||||
width: 0,
|
width: 0,
|
||||||
|
@ -50,7 +50,7 @@ const CollapsibleContainer: React.VoidFunctionComponent<{
|
||||||
className={className}
|
className={className}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</motion.div>
|
</m.div>
|
||||||
) : null}
|
) : null}
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
);
|
);
|
||||||
|
@ -61,14 +61,14 @@ const PopInOut: React.VoidFunctionComponent<{
|
||||||
className?: string;
|
className?: string;
|
||||||
}> = ({ children, className }) => {
|
}> = ({ children, className }) => {
|
||||||
return (
|
return (
|
||||||
<motion.div
|
<m.div
|
||||||
initial={{ scale: 0 }}
|
initial={{ scale: 0 }}
|
||||||
animate={{ scale: 1 }}
|
animate={{ scale: 1 }}
|
||||||
exit={{ scale: 0 }}
|
exit={{ scale: 0 }}
|
||||||
className={clsx(className)}
|
className={clsx(className)}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</motion.div>
|
</m.div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ const PollOptionVoteSummary: React.VoidFunctionComponent<{ optionId: string }> =
|
||||||
participantsWhoVotedYes.length + participantsWhoVotedIfNeedBe.length ===
|
participantsWhoVotedYes.length + participantsWhoVotedIfNeedBe.length ===
|
||||||
0;
|
0;
|
||||||
return (
|
return (
|
||||||
<motion.div
|
<m.div
|
||||||
transition={{
|
transition={{
|
||||||
duration: 0.1,
|
duration: 0.1,
|
||||||
}}
|
}}
|
||||||
|
@ -145,7 +145,7 @@ const PollOptionVoteSummary: React.VoidFunctionComponent<{ optionId: string }> =
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</m.div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -228,7 +228,7 @@ const PollOption: React.VoidFunctionComponent<PollOptionProps> = ({
|
||||||
<div className="mr-3 shrink-0 grow">{children}</div>
|
<div className="mr-3 shrink-0 grow">{children}</div>
|
||||||
<AnimatePresence initial={false}>
|
<AnimatePresence initial={false}>
|
||||||
{editable ? null : (
|
{editable ? null : (
|
||||||
<motion.button
|
<m.button
|
||||||
exit={{ opacity: 0, x: -10 }}
|
exit={{ opacity: 0, x: -10 }}
|
||||||
type="button"
|
type="button"
|
||||||
onTouchStart={(e) => e.stopPropagation()}
|
onTouchStart={(e) => e.stopPropagation()}
|
||||||
|
@ -249,7 +249,7 @@ const PollOption: React.VoidFunctionComponent<PollOptionProps> = ({
|
||||||
},
|
},
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</motion.button>
|
</m.button>
|
||||||
)}
|
)}
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
<div className="mx-3">
|
<div className="mx-3">
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { AnimatePresence, motion } from "framer-motion";
|
import { AnimatePresence, m } from "framer-motion";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { usePrevious } from "react-use";
|
import { usePrevious } from "react-use";
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ export const ScoreSummary: React.VoidFunctionComponent<PopularityScoreProps> =
|
||||||
>
|
>
|
||||||
<CheckCircle className="inline-block h-4 text-slate-300 transition-opacity" />
|
<CheckCircle className="inline-block h-4 text-slate-300 transition-opacity" />
|
||||||
<AnimatePresence initial={false} exitBeforeEnter={true}>
|
<AnimatePresence initial={false} exitBeforeEnter={true}>
|
||||||
<motion.span
|
<m.span
|
||||||
transition={{
|
transition={{
|
||||||
duration: 0.1,
|
duration: 0.1,
|
||||||
}}
|
}}
|
||||||
|
@ -40,7 +40,7 @@ export const ScoreSummary: React.VoidFunctionComponent<PopularityScoreProps> =
|
||||||
className="relative"
|
className="relative"
|
||||||
>
|
>
|
||||||
{score}
|
{score}
|
||||||
</motion.span>
|
</m.span>
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { motion } from "framer-motion";
|
import { m } from "framer-motion";
|
||||||
import { useTranslation } from "next-i18next";
|
import { useTranslation } from "next-i18next";
|
||||||
import posthog from "posthog-js";
|
import posthog from "posthog-js";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
@ -16,7 +16,7 @@ export interface UserDetailsProps {
|
||||||
email?: string;
|
email?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MotionButton = motion(Button);
|
const MotionButton = m(Button);
|
||||||
|
|
||||||
export const UserDetails: React.VoidFunctionComponent<UserDetailsProps> = ({
|
export const UserDetails: React.VoidFunctionComponent<UserDetailsProps> = ({
|
||||||
userId,
|
userId,
|
||||||
|
|
|
@ -12,7 +12,7 @@ import {
|
||||||
useRole,
|
useRole,
|
||||||
} from "@floating-ui/react-dom-interactions";
|
} from "@floating-ui/react-dom-interactions";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import { AnimatePresence, motion } from "framer-motion";
|
import { AnimatePresence, m } from "framer-motion";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
|
||||||
import { preventWidows } from "@/utils/prevent-widows";
|
import { preventWidows } from "@/utils/prevent-widows";
|
||||||
|
@ -104,7 +104,7 @@ const Tooltip: React.VoidFunctionComponent<TooltipProps> = ({
|
||||||
<FloatingPortal>
|
<FloatingPortal>
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
{open ? (
|
{open ? (
|
||||||
<motion.div
|
<m.div
|
||||||
className="z-30 rounded-md bg-slate-700 px-3 py-2 text-slate-200 shadow-md"
|
className="z-30 rounded-md bg-slate-700 px-3 py-2 text-slate-200 shadow-md"
|
||||||
initial="hidden"
|
initial="hidden"
|
||||||
transition={{
|
transition={{
|
||||||
|
@ -140,7 +140,7 @@ const Tooltip: React.VoidFunctionComponent<TooltipProps> = ({
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{typeof content === "string" ? preventWidows(content) : content}
|
{typeof content === "string" ? preventWidows(content) : content}
|
||||||
</motion.div>
|
</m.div>
|
||||||
) : null}
|
) : null}
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
</FloatingPortal>
|
</FloatingPortal>
|
||||||
|
|
|
@ -4,6 +4,7 @@ import "~/style.css";
|
||||||
|
|
||||||
import { Inter, Noto_Sans_Mono } from "@next/font/google";
|
import { Inter, Noto_Sans_Mono } from "@next/font/google";
|
||||||
import { inject } from "@vercel/analytics";
|
import { inject } from "@vercel/analytics";
|
||||||
|
import { domAnimation, LazyMotion, m } from "framer-motion";
|
||||||
import { NextPage } from "next";
|
import { NextPage } from "next";
|
||||||
import { AppProps } from "next/app";
|
import { AppProps } from "next/app";
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
|
@ -15,7 +16,6 @@ import { Toaster } from "react-hot-toast";
|
||||||
import Maintenance from "@/components/maintenance";
|
import Maintenance from "@/components/maintenance";
|
||||||
|
|
||||||
import { useCrispChat } from "../components/crisp-chat";
|
import { useCrispChat } from "../components/crisp-chat";
|
||||||
import ModalProvider from "../components/modal/modal-provider";
|
|
||||||
import { NextPageWithLayout } from "../types";
|
import { NextPageWithLayout } from "../types";
|
||||||
import { absoluteUrl } from "../utils/absolute-url";
|
import { absoluteUrl } from "../utils/absolute-url";
|
||||||
import { UserSession } from "../utils/auth";
|
import { UserSession } from "../utils/auth";
|
||||||
|
@ -89,7 +89,17 @@ const MyApp: NextPage<AppPropsWithLayout> = ({ Component, pageProps }) => {
|
||||||
--font-noto: ${noto.style.fontFamily};
|
--font-noto: ${noto.style.fontFamily};
|
||||||
}
|
}
|
||||||
`}</style>
|
`}</style>
|
||||||
<ModalProvider>{getLayout(<Component {...pageProps} />)}</ModalProvider>
|
<LazyMotion features={domAnimation}>
|
||||||
|
{getLayout(
|
||||||
|
<m.div
|
||||||
|
initial={{ opacity: 0, y: -50 }}
|
||||||
|
animate={{ opacity: 1, y: 0 }}
|
||||||
|
exit={{ opacity: 0, y: 50 }}
|
||||||
|
>
|
||||||
|
<Component {...pageProps} />
|
||||||
|
</m.div>,
|
||||||
|
)}
|
||||||
|
</LazyMotion>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue