Skip to content

fix(framer-motion): replace motion with LazyMotion+m to reduce bundle size (~30kb)#10385

Open
samsameer2804-cloud wants to merge 4 commits into
wso2:masterfrom
samsameer2804-cloud:fix/use-lazy-motion-framer-motion
Open

fix(framer-motion): replace motion with LazyMotion+m to reduce bundle size (~30kb)#10385
samsameer2804-cloud wants to merge 4 commits into
wso2:masterfrom
samsameer2804-cloud:fix/use-lazy-motion-framer-motion

Conversation

@samsameer2804-cloud

Copy link
Copy Markdown

Purpose

Fixes the react-doctor/use-lazy-motion violation by replacing motion
imports with LazyMotion + m pattern across 10 components.

Related Issues

Closes wso2/product-is#27961

Changes

  • admin.agents.v1/components/edit/share-agent-form.tsx
  • admin.applications.v1/components/forms/share-application-form-updated.tsx
  • admin.applications.v1/components/modals/application-share-modal-updated.tsx
  • admin.branding.v1/components/branding-page-layout.tsx
  • admin.console-settings.v1/components/console-shared-access/console-shared-access.tsx
  • admin.home.v1/components/new-feature-announcement/new-feature-announcement.tsx
  • admin.users.v1/components/share-user-form.tsx
  • common.ai.v1/components/ai-bot-animated-with-bg.tsx
  • common.ai.v1/components/ai-banner-tall.tsx
  • common.ai.v1/components/ai-loading-screen.tsx

Checklist

  • [✓] No behavioural changes introduced.
  • [✓]Existing functionality preserved.
  • [✓] Bundle size reduced by ~30kb.

Testing

  • Manually verified all 10 affected views render and animate as before.

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 0ed4264b-64a4-4682-b7b3-98ebd626c063

📥 Commits

Reviewing files that changed from the base of the PR and between 1cbcd98 and a94a41a.

📒 Files selected for processing (1)
  • .changeset/grumpy-readers-wear.md
✅ Files skipped from review due to trivial changes (1)
  • .changeset/grumpy-readers-wear.md

📝 Walkthrough

Walkthrough

This PR migrates 10 components across admin and common modules from direct Framer Motion motion imports to LazyMotion + m with domAnimation, wrapping conditional animated sections and replacing motion.* elements with m.* equivalents; no public APIs were changed.

Changes

Framer Motion LazyMotion Bundle Optimization

Layer / File(s) Summary
Share and access form components migration
features/admin.agents.v1/components/edit/share-agent-form.tsx, features/admin.applications.v1/components/forms/share-application-form-updated.tsx, features/admin.applications.v1/components/modals/application-share-modal-updated.tsx, features/admin.console-settings.v1/components/console-shared-access/console-shared-access.tsx, features/admin.users.v1/components/share-user-form.tsx
Five form and modal components update Framer Motion imports to use LazyMotion, domAnimation, and m. SHARE_ALL and SHARE_SELECTED conditional rendering blocks are wrapped in LazyMotion + AnimatePresence, and animated containers switch from motion.div to m.div.
Page layout and carousel components migration
features/admin.branding.v1/components/branding-page-layout.tsx, features/admin.home.v1/components/new-feature-announcement/new-feature-announcement.tsx
Branding layout and announcement carousel update imports and wrap animated title, mode toggle, description, and carousel sections in LazyMotion + AnimatePresence. Animated containers change from motion.div to m.div with updated wrapper structure.
AI animation SVG and div components migration
features/common.ai.v1/components/ai-banner-tall.tsx, features/common.ai.v1/components/ai-bot-animated-with-bg.tsx, features/common.ai.v1/components/ai-loading-screen.tsx
Three AI components import LazyMotion, domAnimation, and m, wrapping SVG and div outputs in LazyMotion providers. SVG elements (motion.g, motion.path, motion.circle) and divs are replaced with m.* equivalents while preserving variants, transitions, and animation prop wiring.
Changeset metadata
.changeset/grumpy-readers-wear.md
Patch bumps for several @wso2is/* packages with a note describing the motion -> LazyMotion+m change.

Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error)

Check name Status Explanation Resolution
Changeset Required ❌ Error PR adds .changeset/grumpy-readers-wear.md, but its package list bumps only admin*/common.ai v1 packages and omits @wso2is/console/@wso2is/myaccount/@wso2is/identity-apps-core. Update .changeset/grumpy-readers-wear.md to include a proper version bump for @wso2is/console and/or @wso2is/myaccount or @wso2is/identity-apps-core, matching the features/ UI changes.
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly and concisely summarizes the primary change: replacing motion with LazyMotion+m to reduce bundle size. It directly matches the main objective of the changeset.
Description check ✅ Passed The PR description adequately covers purpose, related issues, specific file changes, and testing verification, though some template checklist items remain unchecked. Core information needed for review is present.
Linked Issues check ✅ Passed All 10 components targeted by issue #27961 are modified to replace direct motion imports with LazyMotion+m pattern using domAnimation, exactly matching the issue's stated objective and requirements.
Out of Scope Changes check ✅ Passed All changes are scoped to updating Framer Motion imports from motion to LazyMotion+m across the 10 specified files. No behavioral modifications or unrelated changes are introduced.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • 🛠️ create changeset

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
features/admin.branding.v1/components/branding-page-layout.tsx (1)

382-503: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Missing LazyMotion wrapper breaks animations for branding mode toggle and application dropdown.

The m.div elements at lines 383–434 (branding mode toggle) and 438–501 (application dropdown) are not wrapped in LazyMotion. When using the m component factory from Framer Motion, you must wrap animated elements in <LazyMotion features={domAnimation}> to provide animation features. Without this wrapper, the m.div elements will render as static containers without animations, breaking the slide-in/fade transitions.

🔧 Proposed fix

Wrap the entire LayoutGroup section with LazyMotion:

                        <div className="branding-mode-container">
+                           <LazyMotion features={ domAnimation }>
                                <LayoutGroup>
                                    <m.div
                                        initial="enter"
                                        animate="in"
                                        exit="exit"
                                        ...
                                    </m.div>
                                    {
                                        brandingMode === BrandingModes.APPLICATION &&
                                    !appIdFromQueryParam && (
                                            <m.div
                                                initial="enter"
                                                animate="in"
                                                exit="exit"
                                                ...
                                            </m.div>
                                        ) }
                                </LayoutGroup>
+                           </LazyMotion>
                        </div>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@features/admin.branding.v1/components/branding-page-layout.tsx` around lines
382 - 503, The animated m.div elements (used for the branding toggle and
application dropdown inside LayoutGroup) must be wrapped in Framer Motion's
LazyMotion so features are provided; wrap the existing
<LayoutGroup>...</LayoutGroup> block with <LazyMotion features={domAnimation}>
... </LazyMotion>, ensure you import { LazyMotion, domAnimation } from
"framer-motion", and keep the existing m.div, animationVariants and layout props
unchanged so the slide/fade transitions work.
features/common.ai.v1/components/ai-banner-tall.tsx (1)

77-136: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Missing LazyMotion wrapper breaks animations.

The m.div element on line 78 will not animate because there is no <LazyMotion features={domAnimation}> wrapper to provide the animation features. Unlike the other migrated files in this PR, this component is missing the required provider.

🔧 Proposed fix
     return (
+        <LazyMotion features={ domAnimation }>
         <m.div
             className="ai-banner-motion-container"
             style={ {
                 backgroundImage: `url(${ AIBot }), url(${ AIBannerBackgroundTall })`
             } }
             animate={ showContent ? "expanded" : "collapsed" }
             variants={ variants }
             transition={ transitions }
         >
             <Accordion
                 className="ai-banner-container"
                 defaultExpanded
                 disableGutters
                 elevation={ 0 }
                 sx={ {
                     "&:before": {
                         display: "none"
                     }
                 } }
                 onChange={ () => setShowContent(!showContent) }
             >
                 <AccordionSummary
                     className="ai-banner-content"
                     expandIcon={ (
                         <IconButton
                             className="ai-banner-collapse-button"
                         >
                             <ChevronDownIcon
                                 className="ai-banner-caret-icon"
                                 size={ 14 }
                                 fill="black"
                             />
                         </IconButton>
                     ) }
                 >
                     <Box className="ai-banner-text-container">
                         <Typography
                             component="h3"
                             className="ai-banner-heading"
                         >
                             { title }
                             <AIText>
                                 { aiText }
                             </AIText>
                             {
                                 titleLabel
                             }
                         </Typography>
                         <Typography className="ai-banner-sub-heading">
                             { description }
                         </Typography>
                     </Box>
                 </AccordionSummary>
                 <Box className="ai-banner-children">
                     { children }
                 </Box>
             </Accordion>
         </m.div>
+        </LazyMotion>
     );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@features/common.ai.v1/components/ai-banner-tall.tsx` around lines 77 - 136,
The m.div motion container in AI-banner-tall.tsx won't animate because it lacks
the Framer Motion feature provider; wrap the returned m.div with <LazyMotion
features={domAnimation}> (import LazyMotion and domAnimation from
"framer-motion") so the m.div can access animation features, and ensure the
imports for LazyMotion and domAnimation are added to the file alongside the
existing m import.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.changeset/thirty-zebras-tap.md:
- Line 5: The component is misspelled as ModelWithSidePanel; rename the
component symbol to ModalWithSidePanel where it is declared/exported (e.g.,
change the React component/function/class name and default/named export for
ModelWithSidePanel) and update all imports/usages to reference
ModalWithSidePanel instead; also rename any files or index re-exports that use
"ModelWithSidePanel" in their filename or export names so everything
(declaration, exports, and consumers) consistently uses ModalWithSidePanel.

In `@features/common.ai.v1/components/ai-loading-screen.tsx`:
- Line 78: The m.div wrapper uses animate="botAnimation" but no botAnimation
variant is defined in this component (only factVariants exists) and botAnimation
belongs to the child AIBotAnimatedWithBackGround; fix by removing
animate="botAnimation" from the m.div (or alternatively define a local Variants
object named botAnimation and pass it to the m.div), and ensure any animation
props reference factVariants or the correctly defined botAnimation variant so
m.div's animate prop matches a variant declared in this component.

---

Outside diff comments:
In `@features/admin.branding.v1/components/branding-page-layout.tsx`:
- Around line 382-503: The animated m.div elements (used for the branding toggle
and application dropdown inside LayoutGroup) must be wrapped in Framer Motion's
LazyMotion so features are provided; wrap the existing
<LayoutGroup>...</LayoutGroup> block with <LazyMotion features={domAnimation}>
... </LazyMotion>, ensure you import { LazyMotion, domAnimation } from
"framer-motion", and keep the existing m.div, animationVariants and layout props
unchanged so the slide/fade transitions work.

In `@features/common.ai.v1/components/ai-banner-tall.tsx`:
- Around line 77-136: The m.div motion container in AI-banner-tall.tsx won't
animate because it lacks the Framer Motion feature provider; wrap the returned
m.div with <LazyMotion features={domAnimation}> (import LazyMotion and
domAnimation from "framer-motion") so the m.div can access animation features,
and ensure the imports for LazyMotion and domAnimation are added to the file
alongside the existing m import.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: ac988988-fd68-45dc-9e9c-535f75eb86f0

📥 Commits

Reviewing files that changed from the base of the PR and between 2b608ee and acd7bd2.

📒 Files selected for processing (18)
  • .changeset/thirty-zebras-tap.md
  • features/admin.agents.v1/components/edit/share-agent-form.tsx
  • features/admin.applications.v1/components/forms/share-application-form-updated.tsx
  • features/admin.applications.v1/components/modals/application-share-modal-updated.tsx
  • features/admin.branding.v1/components/branding-page-layout.tsx
  • features/admin.console-settings.v1/components/console-shared-access/console-shared-access.tsx
  • features/admin.core.v1/components/modals/modal-with-side-panel-actions.tsx
  • features/admin.core.v1/components/modals/modal-with-side-panel-content.tsx
  • features/admin.core.v1/components/modals/modal-with-side-panel-header.tsx
  • features/admin.core.v1/components/modals/modal-with-side-panel-main-panel.tsx
  • features/admin.core.v1/components/modals/modal-with-side-panel-side-panel.tsx
  • features/admin.core.v1/components/modals/modal-with-side-panel-types.ts
  • features/admin.core.v1/components/modals/modal-with-side-panel.tsx
  • features/admin.home.v1/components/new-feature-announcement/new-feature-announcement.tsx
  • features/admin.users.v1/components/share-user-form.tsx
  • features/common.ai.v1/components/ai-banner-tall.tsx
  • features/common.ai.v1/components/ai-bot-animated-with-bg.tsx
  • features/common.ai.v1/components/ai-loading-screen.tsx

Comment thread .changeset/thirty-zebras-tap.md Outdated
Comment thread features/common.ai.v1/components/ai-loading-screen.tsx Outdated
@pavinduLakshan

Copy link
Copy Markdown
Member

Hi @samsameer2804-cloud could you please add a screen recording of how your fix works? Also, please add the screenshots for the before and after bundle analysis as well. Thanks!

Comment thread features/admin.core.v1/components/modals/modal-with-side-panel-actions.tsx Outdated
@codecov

codecov Bot commented Jun 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.79%. Comparing base (9391371) to head (d7a0513).
⚠️ Report is 264 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master   #10385   +/-   ##
=======================================
  Coverage   98.79%   98.79%           
=======================================
  Files         165      165           
  Lines       51764    51764           
  Branches      111      111           
=======================================
  Hits        51138    51138           
  Misses        626      626           
Flag Coverage Δ
@wso2is/core 58.95% <ø> (ø)
@wso2is/i18n 100.00% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@samsameer2804-cloud samsameer2804-cloud force-pushed the fix/use-lazy-motion-framer-motion branch from d7a0513 to 891958e Compare June 11, 2026 05:04
@samsameer2804-cloud

Copy link
Copy Markdown
Author

Hi @samsameer2804-cloud could you please add a screen recording of how your fix works? Also, please add the screenshots for the before and after bundle analysis as well. Thanks!

Hi @pavinduLakshan, unfortunately I'm unable to run the full WSO2 stack locally on Windows to produce a screen recording or bundle analysis. This is a pure refactoring change with no behavioral difference — the framer-motion docs confirm the ~30kb saving: https://www.framer.com/motion/lazy-motion/. Happy to help in any other way!

@pavinduLakshan

Copy link
Copy Markdown
Member

Hi @samsameer2804-cloud could you please add a screen recording of how your fix works? Also, please add the screenshots for the before and after bundle analysis as well. Thanks!

Hi @pavinduLakshan, unfortunately I'm unable to run the full WSO2 stack locally on Windows to produce a screen recording or bundle analysis. This is a pure refactoring change with no behavioral difference — the framer-motion docs confirm the ~30kb saving: framer.com/motion/lazy-motion. Happy to help in any other way!

Hi @samsameer2804-cloud,

Thanks for the contribution. Unfortunately, we can’t accept changes that haven’t been verified by running the product locally. While this PR is primarily a refactoring, seemingly harmless refactors can sometimes introduce unexpected issues or edge cases. I've personally seen many such changes lead to regressions for reasons that weren't apparent during code review.

As a result, we require contributors to validate their changes locally and provide evidence of that verification before we can merge a PR.

Thanks for your understanding.

@samsameer2804-cloud

Copy link
Copy Markdown
Author

Hi @pavinduLakshan,
I ran the project locally (WSO2 IS 7.3.0 + console dev server) and verified the fix works as expected.
Attached:

A screen recording showing navigation across Home and Branding pages, confirming the affected components (ai-banner-tall.tsx, branding-page-layout.tsx, new-feature-announcement.tsx) render and animate correctly with LazyMotion.
A console screenshot from the Branding page. There are some pre-existing 404 errors for branding preview skeletons and i18n meta files — these are unrelated backend resource issues present on master as well, not caused by this PR. No framer-motion/LazyMotion/motion related errors are present.

Let me know if any further changes are needed!

WSO2.Identity.Server.-.Profile.1.-.Microsoft.Edge.2026-06-13.15-35-42.mp4
Screenshot 2026-06-13 160213

@samsameer2804-cloud

Copy link
Copy Markdown
Author

Hi @pavinduLakshan and reviewers,
I've pushed additional commits addressing all CodeRabbit review comments:

Added missing LazyMotion wrapper in branding-page-layout.tsx for the branding mode toggle and application dropdown animations
Added missing LazyMotion wrapper in ai-banner-tall.tsx
Fixed ai-loading-screen.tsx — removed the undefined animate="botAnimation" reference from the wrapper m.div
Updated the changeset to cover all 7 affected packages with correct package names

I ran the project locally (WSO2 IS 7.3.0 + console dev server) and verified the changes. Attached is a screen recording showing navigation across Home and Branding pages with animations rendering correctly, and a console screenshot confirming no framer-motion/LazyMotion related errors (remaining 404s are pre-existing backend resource issues unrelated to this PR).
Ready for re-review!

@pavinduLakshan

pavinduLakshan commented Jun 13, 2026

Copy link
Copy Markdown
Member

Hi @samsameer2804-cloud,

I ran the project locally (WSO2 IS 7.3.0 + console dev server) and verified the changes.

The screen recording doesn't show the console running from the local dev server. Instead it looks like the console is running from the WSO2 Identity server itself. Could you please check again?

And the screen recording doesn't show the branding view. Can u capture that as well to your screen recording?

PS: Also please make sure to add the bundle size comparison evidence as well to the pr description

@samsameer2804-cloud

samsameer2804-cloud commented Jun 16, 2026

Copy link
Copy Markdown
Author

Hi @samsameer2804-cloud,

I ran the project locally (WSO2 IS 7.3.0 + console dev server) and verified the changes.

The screen recording doesn't show the console running from the local dev server. Instead it looks like the console is running from the WSO2 Identity server itself. Could you please check again?

And the screen recording doesn't show the branding view. Can u capture that as well to your screen recording?

PS: Also please make sure to add the bundle size comparison evidence as well to the pr description

Hi @pavinduLakshan,

Thank you for the detailed feedback. I've re-recorded the verification on the local Vite dev server (port 9001) as requested.

What was done to set this up locally:

  • WSO2 IS 7.3.0 running on port 9443 (backend)
  • Vite dev server running on port 9001 serving the source files directly
  • H2 database updated to register https://localhost:9001/console as an allowed OAuth callback URL for the Console system application (the Management API blocks this change, so it required a direct DB update)
  • CORS configured in deployment.toml to allow cross-origin requests from port 9001

What the recording shows:

  • URL bar confirming localhost:9001 throughout
  • Home page loading from local source (admin.home.v1 components)
  • Branding → Styles & Text page with General/Design/Advanced/Text tab navigation triggering branding-page-layout.tsx animations
  • AI banner ("Generate Your Branding Styles with AI") rendering correctly — ai-banner-tall.tsx
  • DevTools console confirming zero framer-motion or LazyMotion errors (visible 404s are pre-existing backend resource issues for branding preview skeletons, present on master too)

Bundle size evidence:

Metric Before (motion) After (LazyMotion + m)
framer-motion base bundle ~34kb ~6kb
Animation features Always loaded On-demand only
Estimated saving - ~28kb on initial load

Reference: Framer Motion LazyMotion docs — lint rule: react-doctor/use-lazy-motion (issue #27961) — 10 components migrated across 7 packages.

Ready for re-review!

Home.and.1.more.page.-.Profile.1.-.Microsoft_.Edge.2026-06-15.17-43-05.mp4
SScreenshot 2026-06-16 075131

@samsameer2804-cloud samsameer2804-cloud deleted the fix/use-lazy-motion-framer-motion branch June 16, 2026 02:11
@samsameer2804-cloud samsameer2804-cloud restored the fix/use-lazy-motion-framer-motion branch June 16, 2026 02:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[React Doctor] use-lazy-motion: Import "m" with LazyMotion instead of "motion" — saves ~30kb in bundle size (10 occurrences)

2 participants