Skip to content

feat(fab): modernize FAB to MD3 - #4963

Merged
adrcotfas merged 3 commits into
mainfrom
@adrcotfas/fab
Jun 9, 2026
Merged

feat(fab): modernize FAB to MD3#4963
adrcotfas merged 3 commits into
mainfrom
@adrcotfas/fab

Conversation

@adrcotfas

@adrcotfasadrcotfas commented May 22, 2026

Copy link
Copy Markdown
Collaborator

Motivation

Rework the FAB family to follow Material Design 3, replacing the legacy
FAB, FAB.Group, and AnimatedFAB with a token-driven implementation.

  • New variant prop (primary, secondary, tertiary, tonalPrimary,
    tonalSecondary, tonalTertiary) drives role-based coloring, defaulting
    to tonalPrimary.
  • New size prop (default, medium, large) replaces the old small /
    customSize sizing, with shape and metrics sourced from spec tokens.
  • visible toggling now animates the spec'd enter/exit (scale + alpha)
    on the FAB itself.
  • Add FAB.Extended for the extended (icon + label) FAB.
  • Add FAB.Menu (with Menu, MenuItem, MenuTrigger) to replace the old
    FAB.Group speed-dial pattern.
  • Add a keyboard focus ring (web) and shared visibility animation hook.
  • Split the implementation into Shell, Content, Extended, Menu, tokens,
    useFocusRing, and useVisibility for clarity.

BREAKING CHANGE: The FAB API has been redesigned for MD3 with no
deprecation aliases.

  • AnimatedFAB and AnimatedFABProps are removed. Use FAB.Extended
    for the icon + label FAB.
  • FAB.Group and FABGroupProps are removed. Use FAB.Menu instead.
  • The legacy FAB props (mode, small, color, label, uppercase,
    customSize, animated) are removed. Use variant, size,
    containerColor, and contentColor instead; for a labeled FAB switch
    to FAB.Extended.
  • New exported types: FABExtendedProps, FABMenuProps,
    FABMenuItemProps, FABMenuTriggerProps, FABVariant, FABSize.

Related issue

#4959

Test plan

  • Lint, typescript, existing and new tests pass
  • manual visual inspection on all platforms

@adrcotfasadrcotfas self-assigned this May 22, 2026
@github-actions

Copy link
Copy Markdown

The mobile version of example app from this branch is ready! You can see it here.

@adrcotfas
adrcotfasforce-pushed the @adrcotfas/tokens_structure branch 3 times, most recently from b41006a to f675bafCompareMay 26, 2026 12:06
Base automatically changed from @adrcotfas/tokens_structure to mainMay 26, 2026 12:14
@adrcotfas
adrcotfasforce-pushed the @adrcotfas/fab branch 2 times, most recently from ea933f4 to fb3266aCompareMay 27, 2026 13:38
@adrcotfas
adrcotfas marked this pull request as ready for review May 27, 2026 13:39
@adrcotfas
adrcotfas requested a review from satya164May 27, 2026 13:41
@satya164
satya164 requested a review from CopilotJune 2, 2026 08:33

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR is a major rewrite of the FAB family to align with the latest MD3 / MD3 Expressive specs. The legacy FAB, FAB.Group, and AnimatedFAB components (and all their tests/snapshots) are deleted and replaced with a new component family — FloatingActionButton, ExtendedFloatingActionButton, FloatingActionButtonMenu — built on top of two new internal primitives (FabShell, FabContent) and Reanimated-based hooks (useFabVisibility, useFocusRing). New token tables, a shared resolveCornerRadius shape utility, and a Reanimated-driven morphing trigger for the menu are introduced. The example/ app and Babel rewrite-imports fixture are updated to use the new public names.

Changes:

  • Replace FAB/FABGroup/AnimatedFAB with FloatingActionButton, ExtendedFloatingActionButton, and FloatingActionButtonMenu, all sharing a new internal FabShell/FabContent infrastructure and MD3 token tables.
  • Introduce Reanimated-based visibility/focus-ring hooks, a resolveCornerRadius theme utility, and a morphing trigger that animates between the FAB icon and a circular close button.
  • Update example screens, docs config, and Babel fixtures to reference the renamed components; remove all prior FAB tests/snapshots without adding replacements.

Reviewed changes

Copilot reviewed 35 out of 36 changed files in this pull request and generated 2 comments.

Show a summary per file
FileDescription
src/components/FAB/FloatingActionButton.tsxNew thin wrapper around FabShell exposing the public icon-only FAB.
src/components/FAB/ExtendedFloatingActionButton.tsxNew extended FAB with width/label spring animation and per-platform label measurement.
src/components/FAB/FloatingActionButtonMenu.tsxNew FAB Menu with stagger animation, morphing close-button trigger, and dev-only item-count warning.
src/components/FAB/FabShell.tsxInternal shared shell: outer container, ripple, clip, focus ring, visibility/shadow animation.
src/components/FAB/FabContent.tsxInternal icon+label row primitive used by all FAB-flavored surfaces.
src/components/FAB/tokens.tsNew MD3 size/variant/state-elevation/menu tokens and focus-ring constants.
src/components/FAB/useFabVisibility.tsNew scale+alpha+shadow visibility hook respecting reduce-motion.
src/components/FAB/useFocusRing.tsNew shared-value focus state with web :focus-visible gating.
src/components/FAB/utils.tsReduced to resolveColors, getDimensions, and getLabelSizeWeb; old helpers removed.
src/components/FAB/FAB.tsx, FABGroup.tsx, AnimatedFAB.tsx, index.tsDeleted legacy implementations.
src/components/tests/FAB.test.tsx, FABGroup.test.tsx, AnimatedFAB.test.tsx (+ snapshots)All FAB-related tests deleted with no replacements.
src/theme/utils/shape.tsNew ShapeToken/resolveCornerRadius helper.
src/index.tsxPublic-API rename: removes FAB/AnimatedFAB, exports new component family + size/variant types.
tsconfig.jsonAdds @testing-library/jest-native to global types.
src/babel/fixtures/rewrite-imports/{code,output}.jsUpdate fixture to the new component name.
example/src/Examples/FABExample.tsxRewritten to demo the new component family with a chip-row control panel.
example/src/Examples/AnimatedFABExample/*Deleted.
example/src/Examples/{Tooltip,TeamDetails,Banner,Appbar,ActivityIndicator}Example.tsx, ExampleList.tsxRenamed FAB usages to FloatingActionButton and adjusted props.
docs/docusaurus.config.js, docs/src/components/BannerExample.tsxUpdate docs to reflect the new components and sizes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadsrc/components/FAB/utils.ts
Comment threadsrc/index.tsx Outdated

@satya164satya164 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

the commit messages (from PR description) will be used for changelog, so lets make it a habit to include user facing description in the commit description. e.g. what removed, what changed, replacements, what user should change in their code, diff example when relevant etc.

for breaking changes, you can put "BREAKING CHANGE:" at the top of the description which makes the changelog generator pick it up.

Comment threadsrc/index.tsx Outdated
Comment threadsrc/index.tsx Outdated
Comment threadexample/src/Examples/AppbarExample.tsx Outdated
Comment threadsrc/components/FAB/ExtendedFloatingActionButton.tsx Outdated
Comment threadsrc/components/FAB/utils.ts Outdated
Comment threadsrc/components/FAB/FloatingActionButtonMenu.tsx Outdated
Comment threadsrc/components/FAB/FloatingActionButtonMenu.tsx Outdated
Comment threadsrc/components/FAB/FloatingActionButtonMenu.tsx Outdated
Comment threadsrc/components/FAB/FloatingActionButtonMenu.tsx Outdated
Comment threadsrc/components/FAB/FloatingActionButtonMenu.tsx Outdated
@satya164

Copy link
Copy Markdown
Member

also noticed the button changing size back and forth on android

CleanShot.2026-06-02.at.13.23.42-optimised.mp4

the shadows don't look correct on iOS and Web. it makes the component look blurry with light background

CleanShot 2026-06-02 at 13 25 12@2x

on android the shadows look better but don't match the ones in MD guidelines - looks darker and less spread out

CleanShot 2026-06-02 at 13 27 13@2x

@adrcotfas

adrcotfas commented Jun 8, 2026

Copy link
Copy Markdown
CollaboratorAuthor

also noticed the button changing size back and forth on android

Fixed

the shadows don't look correct on iOS and Web. it makes the component look blurry with light background

I suspect that the image examples you shared don't follow the specs exactly. It's not the first issue I see in the MD docs. iOS and Web were broken, indeed.

Android delegates the shadow to the OS's top-positioned virtual light model while iOS and Web let us draw a fully parameterized, centered drop shadow, so the looks can't match exactly.

I'm using a native app with FAB to compare and here's the current state.
Web screenshot is pixelated because I increased its size according to the zoomed in emulator/simulator screenshots.

fab_small

@adrcotfas
adrcotfas requested a review from satya164June 8, 2026 16:29
@adrcotfasadrcotfas changed the title feat: Modernize FloatingActionButtonfeat(fab): modernize FAB to MD3Jun 8, 2026
@adrcotfas
adrcotfas enabled auto-merge (rebase) June 9, 2026 11:03
@adrcotfas
adrcotfas disabled auto-merge June 9, 2026 11:03
@adrcotfas
adrcotfas merged commit 6a3310f into mainJun 9, 2026
9 checks passed
@adrcotfas
adrcotfas deleted the @adrcotfas/fab branch June 9, 2026 11:03
@JKobrynskiJKobrynski mentioned this pull request Aug 18, 2026
3 tasks
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@adrcotfas@satya164