feat(chip): distinguish flat-mode selected by background color#4956
feat(chip): distinguish flat-mode selected by background color#4956fabriziocucci wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Pull request overview
Updates Chip MD3 color logic so mode="flat" chips use a transparent fill when unselected and theme.colors.secondaryContainer only when selected, aligning selection visibility with MD3 guidance while keeping outlined-chip behavior unchanged.
Changes:
- Changed default (unselected) flat-chip background from
secondaryContainerto'transparent'. - Refactored selected-chip background color selection to explicitly handle
disabled/outlinedcases and preserve existing outlined behavior. - Updated unit tests and snapshots to lock in the new flat/selected background behavior and related compositions.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
src/components/Chip/helpers.tsx |
Adjusts default and selected background token selection for flat chips. |
src/components/__tests__/Chip.test.tsx |
Adds/updates unit tests covering new background behavior and compositions. |
src/components/__tests__/__snapshots__/Chip.test.tsx.snap |
Updates chip snapshots reflecting transparent unselected flat background. |
src/components/__tests__/__snapshots__/ListItem.test.tsx.snap |
Updates ListItem snapshot impacted by Chip background change. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Hey @fabriziocucci, thank you for your pull request 🤗. The documentation from this branch can be viewed here. |
2aae75f to
69778fa
Compare
Flat chips currently render with `theme.colors.secondaryContainer` for both selected and unselected states. Selection is only visible via the check glyph (when `showSelectedCheck` is set). MD3 spec requires flat chips to use a transparent fill when unselected and the `secondaryContainer` token only when selected. `src/components/Chip/helpers.tsx`: - `getDefaultBackgroundColor` flat branch returns `'transparent'` (was `colors.secondaryContainer`). - `getSelectedBackgroundColor` no longer delegates to `getBackgroundColor`. It returns `colors.secondaryContainer` for flat-selected and `colors.surface` for outlined-selected. `disabled` and `customBackgroundColor` overrides take precedence. Outlined mode is unchanged. Composition with `disabled` and `customBackgroundColor` is preserved. Addresses one bullet from callstack#4931 / callstack#4949 (Chip section, "`flat` mode background is always `secondaryContainer` regardless of `selected` state"). Verified visually on iOS Simulator and Android Emulator across light and dark themes.
69778fa to
d93905a
Compare
| } | ||
|
|
||
| return colors.secondaryContainer; | ||
| return 'transparent'; |
There was a problem hiding this comment.
I think that before changing the background color we should lay the foundation for the updated chips which should be splitting into types - there is no "flat" in the specs.
Also, please double check the specs and visual examples: https://m3.material.io/components/chips/specs.
This PR removes the background from flat chips but there's no equivalent for that in the specs where all chips have at least an outline.
Summary
Adds visual distinction between selected and unselected
flatmode chips. TodayChip mode="flat"renders withtheme.colors.secondaryContainerfor BOTH the unselected and selected states. Selection is only visible via the check glyph (whenshowSelectedCheckis set). MD3 spec calls for flat chips to use a transparent fill when unselected and thesecondaryContainertoken only when selected.This addresses one bullet from #4931 / discussion #4949 (Chip section):
MD3 spec reference: https://m3.material.io/components/chips/specs
Behavior
After the patch, with default props:
flat'transparent'filltheme.colors.secondaryContainerfilloutlinedtheme.colors.surfacefill (unchanged)theme.colors.surfacefill (unchanged; outlined chips show selection via the check glyph, not via background change)Composition with existing props (precedence rules)
customBackgroundColorwins (passed viastyle={{ backgroundColor: ... }}): an explicit override takes precedence over both the unselected and selected token paths.disabledwins: disabled tokens take precedence over the selected fill. Flat-disabled-selected returnssurfaceContainerLow; outlined-disabled-selected returns'transparent'. Matches MD3.surfaceand outlined-selected stayssurface. Outlined chips show selection via the check glyph only, as before.Implementation
src/components/Chip/helpers.tsx:getDefaultBackgroundColor: flat branch returns'transparent'(wascolors.secondaryContainer).getSelectedBackgroundColor: no longer delegates togetBackgroundColor. New body that branches ondisabled,isOutlinedandcustomBackgroundColorto return the correct selected color for each composition.Net: +18 / -7 lines in
helpers.tsx. Outlined mode unchanged. No new public props.Testing
Visually verified on iOS Simulator (iPhone 17 Pro, iOS 18) and Android Emulator (Pixel 9, API 35) across light and dark themes using a standalone Expo app with the patch applied via
patch-package.Unit tests for the new behavior added in
src/components/__tests__/Chip.test.tsx(4 new cases on top of the existing 33):should differ from selectedBackgroundColor for theme version 3, flat mode(the key behavioral contract this PR establishes)should return surface color, for theme version 3, outlined mode(selected, locks down outlined behavior is unchanged)should return disabled fill, for theme version 3, flat mode + disabled(selected, disabled composition)should return transparent for theme version 3, outlined mode + disabled(selected, disabled + outlined composition)The existing
should return theme color, for theme version 3, flat mode(background-color block) was updated to assert'transparent'instead ofsecondaryContainer(the test that previously codified the bug).4 chip snapshots updated (
onPress,icon,close button,custom close button) plus 1 ListItem snapshot (it renders a Chip and captured the old background). All 742 unit tests pass.Screenshots:
iOS
Android
Observations:
secondaryContainertoken but resolved through the dark theme palette. Patch is token-based so any custom theme passed viaPaperProviderJust Works.flat + disabled,flat + custom backgroundColor) were each verified visually.What's NOT in this PR
These were considered and intentionally deferred (each could be its own PR):
assist/filter/input/suggestion) into distinct color logic (separate React Native Paper: MD3 Component Review #4949 bullet about adding atypeprop)elevated=truenot changing background color (separate React Native Paper: MD3 Component Review #4949 bullet)primary, separate React Native Paper: MD3 Component Review #4949 bullet)showSelectedOverlayprop (separate React Native Paper: MD3 Component Review #4949 bullet)PressabletoTouchableRipplefor the MD3 state layer (separate React Native Paper: MD3 Component Review #4949 bullet)Conventional commit
feat(chip): distinguish flat-mode selected by background colorRelated
cc @adrcotfas