diff --git a/apps/web/package.json b/apps/web/package.json index 30efee07a..b119257c3 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -97,7 +97,6 @@ "cors": "^2.8.5", "date-fns": "^4.1.0", "esbuild": "^0.17.8", - "framer-motion": "^9.0.4", "fuse.js": "^7.1.0", "gray-matter": "^4.0.3", "jose": "^5.2.0", @@ -110,6 +109,7 @@ "mitt": "^3.0.0", "monaco-editor": "^0.40.0", "monaco-themes": "^0.4.3", + "motion": "^12.8.0", "negotiator": "^1.0.0", "next": "14.2.15", "next-contentlayer": "^0.3.4", diff --git a/apps/web/src/app/[locale]/(interviews)/(marketing)/InterviewsMarketingHomePageBottomContainer.tsx b/apps/web/src/app/[locale]/(interviews)/(marketing)/InterviewsMarketingHomePageBottomContainer.tsx index eb4a2c4f0..2ce3f1b29 100644 --- a/apps/web/src/app/[locale]/(interviews)/(marketing)/InterviewsMarketingHomePageBottomContainer.tsx +++ b/apps/web/src/app/[locale]/(interviews)/(marketing)/InterviewsMarketingHomePageBottomContainer.tsx @@ -1,7 +1,7 @@ 'use client'; import type { InterviewsStudyList } from 'contentlayer/generated'; -import { useInView } from 'framer-motion'; +import { useInView } from 'motion/react'; import dynamic from 'next/dynamic'; import { useRef } from 'react'; diff --git a/apps/web/src/app/[locale]/projects/(marketing)/ProjectsMarketingHomePage.tsx b/apps/web/src/app/[locale]/projects/(marketing)/ProjectsMarketingHomePage.tsx index c08b5bac5..dda68c64a 100644 --- a/apps/web/src/app/[locale]/projects/(marketing)/ProjectsMarketingHomePage.tsx +++ b/apps/web/src/app/[locale]/projects/(marketing)/ProjectsMarketingHomePage.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useInView } from 'framer-motion'; +import { useInView } from 'motion/react'; import dynamic from 'next/dynamic'; import { useRef } from 'react'; diff --git a/apps/web/src/components/auth/AuthTestimonialSlider.tsx b/apps/web/src/components/auth/AuthTestimonialSlider.tsx index 9431b8aae..34a034948 100644 --- a/apps/web/src/components/auth/AuthTestimonialSlider.tsx +++ b/apps/web/src/components/auth/AuthTestimonialSlider.tsx @@ -1,6 +1,6 @@ import clsx from 'clsx'; -import { AnimatePresence, motion } from 'framer-motion'; import { shuffle } from 'lodash-es'; +import { AnimatePresence, motion } from 'motion/react'; import { useEffect, useRef, useState } from 'react'; import { InterviewsMarketingTestimonialsDict } from '~/components/interviews/marketing/testimonials/InterviewsMarketingTestimonials'; diff --git a/apps/web/src/components/common/TypingString.tsx b/apps/web/src/components/common/TypingString.tsx index 806517e48..ea17bc921 100644 --- a/apps/web/src/components/common/TypingString.tsx +++ b/apps/web/src/components/common/TypingString.tsx @@ -1,4 +1,4 @@ -import { useInView } from 'framer-motion'; +import { useInView } from 'motion/react'; import { useEffect, useRef } from 'react'; import useTypingString from '~/hooks/useTypingString'; diff --git a/apps/web/src/components/interviews/common/InterviewsTestimonialsSlider.tsx b/apps/web/src/components/interviews/common/InterviewsTestimonialsSlider.tsx index 8dfbeef66..241c388f4 100644 --- a/apps/web/src/components/interviews/common/InterviewsTestimonialsSlider.tsx +++ b/apps/web/src/components/interviews/common/InterviewsTestimonialsSlider.tsx @@ -1,7 +1,8 @@ 'use client'; import clsx from 'clsx'; -import { AnimatePresence, motion, wrap } from 'framer-motion'; +import type { PanInfo } from 'motion/react'; +import { AnimatePresence, motion, wrap } from 'motion/react'; import { useEffect, useRef, useState } from 'react'; import type { InterviewsMarketingTestimonial } from '~/components/interviews/marketing/testimonials/InterviewsMarketingTestimonialCard'; @@ -280,7 +281,7 @@ export default function InterviewsTestimonialsSlider({ data }: Props) { x: { damping: 30, stiffness: 300, type: 'spring' }, }} variants={carouselMotionVariants} - onDragEnd={(_, { offset, velocity }) => { + onDragEnd={(_: MouseEvent, { offset, velocity }: PanInfo) => { const swipe = swipePower(offset.x, velocity.x); // Stop auto-advancing if user interacts by swiping. diff --git a/apps/web/src/components/interviews/marketing/InterviewsMarketingContinuousUpdates.tsx b/apps/web/src/components/interviews/marketing/InterviewsMarketingContinuousUpdates.tsx index 31b86d174..97a511bb9 100644 --- a/apps/web/src/components/interviews/marketing/InterviewsMarketingContinuousUpdates.tsx +++ b/apps/web/src/components/interviews/marketing/InterviewsMarketingContinuousUpdates.tsx @@ -1,5 +1,5 @@ import clsx from 'clsx'; -import { motion, useInView, useMotionValue } from 'framer-motion'; +import { motion, useInView, useMotionValue } from 'motion/react'; import { useId, useRef, useState } from 'react'; import LogoMark from '~/components/global/logos/LogoMark'; diff --git a/apps/web/src/components/interviews/marketing/InterviewsMarketingHero.tsx b/apps/web/src/components/interviews/marketing/InterviewsMarketingHero.tsx index 8d465ff8c..05268f0ab 100644 --- a/apps/web/src/components/interviews/marketing/InterviewsMarketingHero.tsx +++ b/apps/web/src/components/interviews/marketing/InterviewsMarketingHero.tsx @@ -1,7 +1,7 @@ 'use client'; import clsx from 'clsx'; -import { useInView } from 'framer-motion'; +import { useInView } from 'motion/react'; import { useRef } from 'react'; import { RiArrowRightLine } from 'react-icons/ri'; diff --git a/apps/web/src/components/interviews/marketing/InterviewsMarketingSolutionsByExInterviewersSection.tsx b/apps/web/src/components/interviews/marketing/InterviewsMarketingSolutionsByExInterviewersSection.tsx index 63f78994e..edff4fe31 100644 --- a/apps/web/src/components/interviews/marketing/InterviewsMarketingSolutionsByExInterviewersSection.tsx +++ b/apps/web/src/components/interviews/marketing/InterviewsMarketingSolutionsByExInterviewersSection.tsx @@ -1,5 +1,5 @@ import clsx from 'clsx'; -import { useInView } from 'framer-motion'; +import { useInView } from 'motion/react'; import type { ReactNode } from 'react'; import { useEffect, useRef, useState } from 'react'; import { RiAmazonFill, RiMetaFill } from 'react-icons/ri'; diff --git a/apps/web/src/components/interviews/marketing/InterviewsMarketingTestCodeSection.tsx b/apps/web/src/components/interviews/marketing/InterviewsMarketingTestCodeSection.tsx index 72acdd62b..7773192ca 100644 --- a/apps/web/src/components/interviews/marketing/InterviewsMarketingTestCodeSection.tsx +++ b/apps/web/src/components/interviews/marketing/InterviewsMarketingTestCodeSection.tsx @@ -1,5 +1,5 @@ import clsx from 'clsx'; -import { motion, useAnimation, useInView } from 'framer-motion'; +import { motion, useAnimation, useInView } from 'motion/react'; import type { RefObject } from 'react'; import { useEffect, useRef, useState } from 'react'; import { RiCheckboxCircleLine, RiCursorLine, RiPlayLine } from 'react-icons/ri'; diff --git a/apps/web/src/components/interviews/marketing/embed/InterviewsMarketingEmbedSection.tsx b/apps/web/src/components/interviews/marketing/embed/InterviewsMarketingEmbedSection.tsx index a8198aa2e..431d4fa13 100644 --- a/apps/web/src/components/interviews/marketing/embed/InterviewsMarketingEmbedSection.tsx +++ b/apps/web/src/components/interviews/marketing/embed/InterviewsMarketingEmbedSection.tsx @@ -7,7 +7,7 @@ import { useInView, useScroll, useTransform, -} from 'framer-motion'; +} from 'motion/react'; import dynamic from 'next/dynamic'; import { useRef, useState } from 'react'; import { useMediaQuery } from 'usehooks-ts'; diff --git a/apps/web/src/components/marketing/affiliates/MarketingAffiliateHero.tsx b/apps/web/src/components/marketing/affiliates/MarketingAffiliateHero.tsx index e6f6fc144..e786c5a5b 100644 --- a/apps/web/src/components/marketing/affiliates/MarketingAffiliateHero.tsx +++ b/apps/web/src/components/marketing/affiliates/MarketingAffiliateHero.tsx @@ -1,5 +1,5 @@ import clsx from 'clsx'; -import { useInView } from 'framer-motion'; +import { useInView } from 'motion/react'; import { useRef } from 'react'; import { RiArrowRightLine } from 'react-icons/ri'; diff --git a/apps/web/src/components/marketing/affiliates/MarketingAffiliateHowDoesItWork.tsx b/apps/web/src/components/marketing/affiliates/MarketingAffiliateHowDoesItWork.tsx index f049063c5..03cc55bdc 100644 --- a/apps/web/src/components/marketing/affiliates/MarketingAffiliateHowDoesItWork.tsx +++ b/apps/web/src/components/marketing/affiliates/MarketingAffiliateHowDoesItWork.tsx @@ -1,5 +1,5 @@ import clsx from 'clsx'; -import { useInView } from 'framer-motion'; +import { useInView } from 'motion/react'; import { useRef } from 'react'; import { FormattedMessage } from '~/components/intl'; diff --git a/apps/web/src/components/marketing/affiliates/MarketingAffiliateWhyJoinUs.tsx b/apps/web/src/components/marketing/affiliates/MarketingAffiliateWhyJoinUs.tsx index 80845b917..5dcc5f507 100644 --- a/apps/web/src/components/marketing/affiliates/MarketingAffiliateWhyJoinUs.tsx +++ b/apps/web/src/components/marketing/affiliates/MarketingAffiliateWhyJoinUs.tsx @@ -1,5 +1,5 @@ import clsx from 'clsx'; -import { useInView } from 'framer-motion'; +import { useInView } from 'motion/react'; import { useRef } from 'react'; import { FormattedMessage } from '~/components/intl'; diff --git a/apps/web/src/components/marketing/contact/MarketingCommunitySection.tsx b/apps/web/src/components/marketing/contact/MarketingCommunitySection.tsx index 7d9644fc2..f2fcacf56 100644 --- a/apps/web/src/components/marketing/contact/MarketingCommunitySection.tsx +++ b/apps/web/src/components/marketing/contact/MarketingCommunitySection.tsx @@ -1,7 +1,7 @@ 'use client'; import clsx from 'clsx'; -import { useInView } from 'framer-motion'; +import { useInView } from 'motion/react'; import { useEffect, useMemo, useRef, useState } from 'react'; import { RiArrowRightSLine } from 'react-icons/ri'; diff --git a/apps/web/src/components/projects/challenges/brief/ProjectsChallengeBriefImageCarousel.tsx b/apps/web/src/components/projects/challenges/brief/ProjectsChallengeBriefImageCarousel.tsx index 56426477c..6dfcb22f6 100644 --- a/apps/web/src/components/projects/challenges/brief/ProjectsChallengeBriefImageCarousel.tsx +++ b/apps/web/src/components/projects/challenges/brief/ProjectsChallengeBriefImageCarousel.tsx @@ -1,5 +1,6 @@ import clsx from 'clsx'; -import { AnimatePresence, motion, wrap } from 'framer-motion'; +import type { PanInfo } from 'motion/react'; +import { AnimatePresence, motion, wrap } from 'motion/react'; import React, { useState } from 'react'; import { RiArrowLeftSLine, RiArrowRightSLine } from 'react-icons/ri'; @@ -116,7 +117,7 @@ export default function ProjectsChallengeBriefImageCarousel({ images }: Props) { x: { damping: 30, stiffness: 300, type: 'spring' }, }} variants={variants} - onDragEnd={(_, { offset, velocity }) => { + onDragEnd={(_: MouseEvent, { offset, velocity }: PanInfo) => { const swipe = swipePower(offset.x, velocity.x); if (swipe < -swipeConfidenceThreshold) { diff --git a/apps/web/src/components/projects/challenges/header/ProjectsChallengeHeaderLayout.tsx b/apps/web/src/components/projects/challenges/header/ProjectsChallengeHeaderLayout.tsx index c9223d3d7..a744eccc6 100644 --- a/apps/web/src/components/projects/challenges/header/ProjectsChallengeHeaderLayout.tsx +++ b/apps/web/src/components/projects/challenges/header/ProjectsChallengeHeaderLayout.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useInView } from 'framer-motion'; +import { useInView } from 'motion/react'; import { useRef } from 'react'; import ProjectsChallengeHeader from './ProjectsChallengeHeader'; diff --git a/apps/web/src/components/projects/notifications/ProjectsNotificationContent.tsx b/apps/web/src/components/projects/notifications/ProjectsNotificationContent.tsx index 5672ccb84..ec0f7b433 100644 --- a/apps/web/src/components/projects/notifications/ProjectsNotificationContent.tsx +++ b/apps/web/src/components/projects/notifications/ProjectsNotificationContent.tsx @@ -1,6 +1,6 @@ import clsx from 'clsx'; -import { useInView } from 'framer-motion'; import { debounce } from 'lodash-es'; +import { useInView } from 'motion/react'; import { useEffect, useRef, useState } from 'react'; import { RiNotification3Line } from 'react-icons/ri'; diff --git a/apps/web/src/components/projects/submissions/ProjectsChallengeSubmissionLockedPage.tsx b/apps/web/src/components/projects/submissions/ProjectsChallengeSubmissionLockedPage.tsx index 893e4b022..aaba0c9c9 100644 --- a/apps/web/src/components/projects/submissions/ProjectsChallengeSubmissionLockedPage.tsx +++ b/apps/web/src/components/projects/submissions/ProjectsChallengeSubmissionLockedPage.tsx @@ -1,7 +1,7 @@ 'use client'; import clsx from 'clsx'; -import { useInView } from 'framer-motion'; +import { useInView } from 'motion/react'; import { useRef } from 'react'; import type { ProjectsChallengeItem } from '~/components/projects/challenges/types'; diff --git a/apps/web/src/components/projects/submissions/ProjectsChallengeSubmissionPage.tsx b/apps/web/src/components/projects/submissions/ProjectsChallengeSubmissionPage.tsx index 998d047d9..97ef8aa98 100644 --- a/apps/web/src/components/projects/submissions/ProjectsChallengeSubmissionPage.tsx +++ b/apps/web/src/components/projects/submissions/ProjectsChallengeSubmissionPage.tsx @@ -1,7 +1,7 @@ 'use client'; import clsx from 'clsx'; -import { useInView } from 'framer-motion'; +import { useInView } from 'motion/react'; import { useEffect, useMemo, useRef } from 'react'; import { RiShareCircleLine } from 'react-icons/ri'; diff --git a/apps/web/src/components/projects/submissions/hero/ProjectsChallengeSubmissionHero.tsx b/apps/web/src/components/projects/submissions/hero/ProjectsChallengeSubmissionHero.tsx index ed470bb6d..ff8a4882a 100644 --- a/apps/web/src/components/projects/submissions/hero/ProjectsChallengeSubmissionHero.tsx +++ b/apps/web/src/components/projects/submissions/hero/ProjectsChallengeSubmissionHero.tsx @@ -1,5 +1,5 @@ import clsx from 'clsx'; -import { useInView } from 'framer-motion'; +import { useInView } from 'motion/react'; import { useRef } from 'react'; import { RiArrowLeftLine, RiMessage2Fill, RiPencilLine } from 'react-icons/ri'; import { useMediaQuery } from 'usehooks-ts'; diff --git a/apps/web/src/components/sponsors/ads/useSponsorsAdImpressionLogging.ts b/apps/web/src/components/sponsors/ads/useSponsorsAdImpressionLogging.ts index 478543b60..478215b0f 100644 --- a/apps/web/src/components/sponsors/ads/useSponsorsAdImpressionLogging.ts +++ b/apps/web/src/components/sponsors/ads/useSponsorsAdImpressionLogging.ts @@ -1,4 +1,4 @@ -import { useInView } from 'framer-motion'; +import { useInView } from 'motion/react'; import { usePathname } from 'next/navigation'; import { useEffect, useRef } from 'react'; diff --git a/apps/web/src/components/ui/AnimatedBeam/AnimatedBeam.tsx b/apps/web/src/components/ui/AnimatedBeam/AnimatedBeam.tsx index 9e9911b77..51d12acfa 100644 --- a/apps/web/src/components/ui/AnimatedBeam/AnimatedBeam.tsx +++ b/apps/web/src/components/ui/AnimatedBeam/AnimatedBeam.tsx @@ -1,7 +1,7 @@ 'use client'; import clsx from 'clsx'; -import { motion } from 'framer-motion'; +import { motion } from 'motion/react'; import type { RefObject } from 'react'; import { useEffect, useId, useState } from 'react'; diff --git a/apps/web/src/components/ui/Marquee/Marquee.tsx b/apps/web/src/components/ui/Marquee/Marquee.tsx index 9ef99ba91..5817418b5 100644 --- a/apps/web/src/components/ui/Marquee/Marquee.tsx +++ b/apps/web/src/components/ui/Marquee/Marquee.tsx @@ -1,5 +1,5 @@ import clsx from 'clsx'; -import { useInView, useReducedMotion } from 'framer-motion'; +import { useInView, useReducedMotion } from 'motion/react'; import { useEffect, useRef, useState } from 'react'; type Direction = 'leftToRight' | 'rightToLeft'; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index dead34e1b..b9d0cda93 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -436,9 +436,6 @@ importers: esbuild: specifier: ^0.17.8 version: 0.17.19 - framer-motion: - specifier: ^9.0.4 - version: 9.1.7(react-dom@18.2.0)(react@18.2.0) fuse.js: specifier: ^7.1.0 version: 7.1.0 @@ -475,6 +472,9 @@ importers: monaco-themes: specifier: ^0.4.3 version: 0.4.4 + motion: + specifier: ^12.8.0 + version: 12.8.0(react-dom@18.2.0)(react@18.2.0) negotiator: specifier: ^1.0.0 version: 1.0.0 @@ -11335,7 +11335,7 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 5.62.0(eslint@8.34.0)(typescript@5.3.3) + '@typescript-eslint/parser': 5.62.0(eslint@8.34.0)(typescript@5.7.2) debug: 3.2.7 eslint: 8.34.0 eslint-import-resolver-node: 0.3.9 @@ -11376,7 +11376,7 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 5.62.0(eslint@8.34.0)(typescript@5.3.3) + '@typescript-eslint/parser': 5.62.0(eslint@8.34.0)(typescript@5.7.2) array-includes: 3.1.7 array.prototype.findlastindex: 1.2.3 array.prototype.flat: 1.3.2 @@ -12076,17 +12076,25 @@ packages: resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} dev: true - /framer-motion@9.1.7(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-nKxBkIO4IPkMEqcBbbATxsVjwPYShKl051yhBv9628iAH6JLeHD0siBHxkL62oQzMC1+GNX73XtPjgP753ufuw==} + /framer-motion@12.8.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-EarL75miCDcKLEAQLJ+6Zfwdj+KQsVlbHGGlygZ/TigKBj7NLPkyDKk4WLFUScjAs2xNpfMRLBM6VsCJq9Roxg==} peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 + '@emotion/is-prop-valid': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true dependencies: + motion-dom: 12.8.0 + motion-utils: 12.7.5 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - tslib: 2.6.2 - optionalDependencies: - '@emotion/is-prop-valid': 0.8.8 + tslib: 2.8.1 dev: false /fs-extra@8.1.0: @@ -15237,6 +15245,36 @@ packages: fast-plist: 0.1.3 dev: false + /motion-dom@12.8.0: + resolution: {integrity: sha512-YsfUE1F8Ycv9th1V0YJ6LOx9U2EMe/8P3RXK1o6NZhRbdFiWvzBLvxqp2X6Fn3rbJbwWkSEfnpe14ZU9Oz1d1Q==} + dependencies: + motion-utils: 12.7.5 + dev: false + + /motion-utils@12.7.5: + resolution: {integrity: sha512-JIgrmEq7Vw1x0AUrjvkRp7oMMQkGqSUMT50O/Ag6RRCQWG3gRRTkOI+BirBAJT6m+GIPoiyxkJ1u98GgF/a6TQ==} + dev: false + + /motion@12.8.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-j03/FAIjwlFSTcr3VIrLFhRTdDyfyyyvJz5s0Ctli3vuv/72+YKEOV2OIC/9QbjDqWU3ChngWlLnFezakCQ3Vg==} + peerDependencies: + '@emotion/is-prop-valid': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true + dependencies: + framer-motion: 12.8.0(react-dom@18.2.0)(react@18.2.0) + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + tslib: 2.8.1 + dev: false + /mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} engines: {node: '>=4'}