Skip to content

feat(checkbox): add error state via MD3 error tokens#4955

Merged
adrcotfas merged 1 commit into
callstack:mainfrom
fabriziocucci:feat/checkbox-error-state
May 20, 2026
Merged

feat(checkbox): add error state via MD3 error tokens#4955
adrcotfas merged 1 commit into
callstack:mainfrom
fabriziocucci:feat/checkbox-error-state

Conversation

@fabriziocucci
Copy link
Copy Markdown
Contributor

@fabriziocucci fabriziocucci commented May 19, 2026

Summary

Adds an error?: boolean prop to Checkbox, CheckboxAndroid and CheckboxIOS. When true, the outline (unchecked) and container (checked / indeterminate) render with theme.colors.error; the checked / indeterminate icon uses theme.colors.onError on Android and theme.colors.error on iOS.

This addresses one bullet from #4937 / discussion #4949 (Checkbox section, "Error state not implemented"):

Error state not implemented. Spec defines error tokens for unselected error outline and selected error container (md.sys.color.error), and onError for the error icon.

MD3 spec reference: https://m3.material.io/components/checkbox/specs

Behavior

When error={true}:

State Unselected Selected Indeterminate
Outline / container theme.colors.error theme.colors.error theme.colors.error
Icon (n/a, outline only) white check inside red container (Android) / red check (iOS) white dash inside red container (Android) / red dash (iOS)

Composition with existing props (precedence rules)

  1. disabled wins: disabled tokens override error entirely. Matches MD3 spec (disabled is the highest-precedence visual state).
  2. color wins for checked: an explicit color prop overrides the error token for the checked container.
  3. Indeterminate state honors error via the unchecked-color path on Android. It does NOT honor a color override (pre-existing v6 behavior, not introduced by this PR). Tracked separately for a focused follow-up.
  4. uncheckedColor wins for unchecked outline only: an explicit uncheckedColor overrides the error token for the unchecked outline; checked / indeterminate states still use the error container.
  5. No error prop = no behavior change: the prop defaults to undefined, so existing usages are byte-for-byte identical.

Implementation

  • src/components/Checkbox/utils.ts: extended getAndroidCheckedColor, getAndroidUncheckedColor, getAndroidSelectionControlColor, getIOSCheckedColor and getSelectionControlIOSColor with an optional error parameter. The error branch sits between custom* (highest precedence) and the theme defaults (lowest), preserving existing behavior when error is unset.
  • src/components/Checkbox/Checkbox.tsx: added error?: boolean to Props with JSDoc.
  • src/components/Checkbox/CheckboxAndroid.tsx: added error to Props, destructured from the component's args, forwarded to getAndroidSelectionControlColor.
  • src/components/Checkbox/CheckboxIOS.tsx: same pattern as Android.

CheckboxItem.tsx is not modified in this PR. That's a follow-up. CheckboxItem would just need to add error?: boolean to its Props and forward to the embedded <Checkbox>. Splitting it keeps this PR focused on the core component.

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 error path added in src/components/__tests__/Checkbox/utils.test.tsx (10 new cases on top of the existing 10):

  • Android: error checked / unchecked / dark mode / disabled-wins / customColor-wins / customUncheckedColor-wins
  • iOS: error / dark mode / disabled-wins / customColor-wins

Screenshots:

iOS

Theme Before After
Light ios-before-light ios-after-light
Dark ios-before-dark ios-after-dark

Android

Theme Before After
Light android-before-light android-after-light
Dark android-before-dark android-after-dark

A few observations:

  • The dark-mode "after" screenshots show salmon-red (#FFB4AB-ish) rather than the light-mode bright red (#B3261E). That's correct. Both come from theme.colors.error, which MD3 specifies separately for the two themes. The patch is token-based so any custom theme passed via PaperProvider Just Works.
  • iOS Checkbox renders no visible box for the unchecked state today (separate concern from this PR, flagged in React Native Paper: MD3 Component Review #4949's Checkbox section), so the "error outline" on iOS unchecked is visually absent. The patch still sets the right color value via getIOSCheckedColor; you'd see it once the unchecked box is added in a future PR.
  • The composition cases (error + disabled, error + color, error + uncheckedColor) were each verified visually.

What's NOT in this PR

These were considered and intentionally deferred (each could be its own PR):

Happy to discuss bundling any of these into this PR if you'd prefer, or to send follow-ups.

Conventional commit

feat(checkbox): add error state via MD3 error tokens

Related

cc @adrcotfas

@callstack-bot
Copy link
Copy Markdown

callstack-bot commented May 19, 2026

Hey @fabriziocucci, thank you for your pull request 🤗. The documentation from this branch can be viewed here.

@fabriziocucci fabriziocucci force-pushed the feat/checkbox-error-state branch from f674da6 to 9e7f48c Compare May 19, 2026 15:25
Copilot AI review requested due to automatic review settings May 19, 2026 15:25
@fabriziocucci fabriziocucci force-pushed the feat/checkbox-error-state branch from 9e7f48c to ed8052a Compare May 19, 2026 15:30
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds an error?: boolean prop to the core Checkbox components to support an MD3-style error visual state by sourcing colors from theme.colors.error (and intended onError for Android icon per PR description), implemented via shared selection-control color utilities.

Changes:

  • Extended Checkbox selection-control color utilities to optionally return theme.colors.error for checked/unchecked states.
  • Added error?: boolean to Checkbox, CheckboxAndroid, and CheckboxIOS props and forwarded it into the color utility functions.
  • Updated component prop documentation (JSDoc) to describe error-state precedence.

Reviewed changes

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

File Description
src/components/Checkbox/utils.ts Adds error handling to Android/iOS color helpers used by Checkbox (and shared selection-control helpers).
src/components/Checkbox/CheckboxAndroid.tsx Adds error prop and forwards it into Android selection-control color computation.
src/components/Checkbox/CheckboxIOS.tsx Adds error prop and forwards it into iOS checked color computation.
src/components/Checkbox/Checkbox.tsx Adds error to the public Checkbox prop type/docs and forwards to platform implementations.
Comments suppressed due to low confidence (1)

src/components/Checkbox/CheckboxAndroid.tsx:119

  • The implementation currently sets selectionControlColor to theme.colors.error when error is true, and that same value is used to tint the Android icon. This doesn’t match the stated behavior/spec of using theme.colors.onError for the check/dash when the container is error. If you want MD3 parity here, the icon color likely needs to be computed separately (e.g., container uses error, glyph uses onError) rather than using a single selectionControlColor for everything.
  const { selectionControlColor, selectionControlOpacity } =
    getAndroidSelectionControlColor({
      theme,
      disabled,
      checked,
      customColor: rest.color,
      customUncheckedColor: rest.uncheckedColor,
      error,
    });

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

Comment thread src/components/Checkbox/CheckboxAndroid.tsx
Comment thread src/components/Checkbox/utils.ts
Adds an `error?: boolean` prop to Checkbox, CheckboxAndroid and
CheckboxIOS. When true, the outline (unchecked) and container (checked /
indeterminate) use `theme.colors.error`. The `disabled` state and
explicit `color` / `uncheckedColor` overrides take precedence.

Addresses one bullet from callstack#4937 / callstack#4949 (Checkbox section,
"Error state not implemented"). Verified visually on iOS Simulator
and Android Emulator across light and dark themes.
@fabriziocucci fabriziocucci force-pushed the feat/checkbox-error-state branch from ed8052a to 8c608fe Compare May 19, 2026 15:45
@fabriziocucci
Copy link
Copy Markdown
Contributor Author

fabriziocucci commented May 19, 2026

Re: the suppressed comment about selectionControlColor not using theme.colors.onError for the glyph. Current rendering uses MaterialCommunityIcon glyphs (checkbox-marked / minus-box) where the check/dash is transparent negative space inside a filled box. Tinting with theme.colors.error produces "red container, surface-color check", equivalent to MD3 container=error + glyph=onError on light surfaces and readable on dark (see screenshots).

Proper compositing (background View + onError-tinted glyph OR different icon family) is a larger architectural change tracked separately under broader #4949 Checkbox rework (state layer, shape tokens, 18dp icon size).

Out of scope for this PR.

@fabriziocucci
Copy link
Copy Markdown
Contributor Author

cc @satya164

@adrcotfas
Copy link
Copy Markdown
Collaborator

adrcotfas commented May 20, 2026

Some general comments:

  • Since you're touching this component and it's not a large one, let's finalize the modernization in one PR
  • Please reuse the same UI between platforms as per MD specs
  • Implement the hover and focus states too (new tokens for focus will be added here: feat: improve structure of ref and sys tokens; add useFocusVisible hook #4952)
  • Improve the Checkbox example page with a parent/child checkbox relationship; parent's state(can be indeterminate when at least one child is toggled off) depends on the state of the children.
  • It's a good moment to replace the checkbox icons with actual drawing so we can fully respect the tokens from the specs
  • Adding a subtle animation like on native would be nice; we already have Reanimated integrated and motion tokens; I can share the native animation implementation if needed.

Edit: I'm fine with handling these in other PRs.

@adrcotfas adrcotfas enabled auto-merge (rebase) May 20, 2026 09:22
@adrcotfas adrcotfas disabled auto-merge May 20, 2026 09:22
@adrcotfas adrcotfas merged commit e860605 into callstack:main May 20, 2026
3 checks passed
@fabriziocucci fabriziocucci deleted the feat/checkbox-error-state branch May 20, 2026 09:33
fabriziocucci added a commit to fabriziocucci/react-native-paper that referenced this pull request May 21, 2026
Per maintainer feedback on callstack#4955, replace the iOS-specific Checkbox
implementation with the Android one (which is closer to the MD3 spec)
and inline the unified implementation directly into Checkbox.tsx.

Changes:
- Checkbox.tsx: inline what was the Android implementation; render the
  same MD3-compliant control on both platforms. Drop the Platform.OS
  dispatching.
- CheckboxAndroid.tsx, CheckboxIOS.tsx: deleted.
- Checkbox/index.ts: `Checkbox.Android` and `Checkbox.IOS` are kept
  as back-compat aliases of `Checkbox` itself, so existing imports
  keep working with no breaking change.
- CheckboxItem.tsx: drop the `mode`-based branching; always render
  `<Checkbox />`. The `mode` prop is kept and marked deprecated.
- src/index.tsx: `CheckboxAndroidProps` and `CheckboxIOSProps` now
  alias the unified `Props` from Checkbox.tsx (no breaking change).
- Snapshot tests updated: the renderer now uses the unified container
  (36x36 ripple) and MaterialCommunityIcon glyphs on both platforms.

`getSelectionControlIOSColor` in utils.ts is intentionally left in
place because RadioButtonIOS still depends on it. A similar unification
for RadioButton can follow in a separate PR.

As a side benefit, callers using `<Checkbox.IOS uncheckedColor=...>`
will now see the prop applied (the old iOS variant silently dropped it),
addressing one of the API-parity gaps noted in callstack#4949.
fabriziocucci added a commit to fabriziocucci/react-native-paper that referenced this pull request May 21, 2026
Per maintainer feedback on callstack#4955, replace the iOS-specific Checkbox
implementation with the Android one (which is closer to the MD3 spec)
and inline the unified implementation directly into Checkbox.tsx.

Changes:
- Checkbox.tsx: inline what was the Android implementation; render the
  same MD3-compliant control on both platforms. Drop the Platform.OS
  dispatching.
- CheckboxAndroid.tsx, CheckboxIOS.tsx: deleted.
- Checkbox/index.ts: `Checkbox.Android` and `Checkbox.IOS` are kept
  as back-compat aliases of `Checkbox` itself, so existing imports
  keep working with no breaking change.
- CheckboxItem.tsx: drop the `mode`-based branching; always render
  `<Checkbox />`. The `mode` prop is kept and marked deprecated.
- src/index.tsx: `CheckboxAndroidProps` and `CheckboxIOSProps` now
  alias the unified `Props` from Checkbox.tsx (no breaking change).
- Snapshot tests updated: the renderer now uses the unified container
  (36x36 ripple) and MaterialCommunityIcon glyphs on both platforms.

`getSelectionControlIOSColor` in utils.ts is intentionally left in
place because RadioButtonIOS still depends on it. A similar unification
for RadioButton can follow in a separate PR.

As a side benefit, callers using `<Checkbox.IOS uncheckedColor=...>`
will now see the prop applied (the old iOS variant silently dropped it),
addressing one of the API-parity gaps noted in callstack#4949.
fabriziocucci added a commit to fabriziocucci/react-native-paper that referenced this pull request May 21, 2026
Per maintainer feedback on callstack#4955, replace the iOS-specific Checkbox
implementation with the Android one (which is closer to the MD3 spec)
and inline the unified implementation directly into Checkbox.tsx.

Changes:
- Checkbox.tsx: inline what was the Android implementation; render the
  same MD3-compliant control on both platforms. Drop the Platform.OS
  dispatching.
- CheckboxAndroid.tsx, CheckboxIOS.tsx: deleted.
- Checkbox/index.ts: `Checkbox.Android` and `Checkbox.IOS` are kept
  as back-compat aliases of `Checkbox` itself, so existing imports
  keep working with no breaking change.
- CheckboxItem.tsx: drop the `mode`-based branching; always render
  `<Checkbox />`. The `mode` prop is kept and marked deprecated.
- src/index.tsx: `CheckboxAndroidProps` and `CheckboxIOSProps` now
  alias the unified `Props` from Checkbox.tsx (no breaking change).
- Snapshot tests updated: the renderer now uses the unified container
  (36x36 ripple) and MaterialCommunityIcon glyphs on both platforms.

`getSelectionControlIOSColor` in utils.ts is intentionally left in
place because RadioButtonIOS still depends on it. A similar unification
for RadioButton can follow in a separate PR.

As a side benefit, callers using `<Checkbox.IOS uncheckedColor=...>`
will now see the prop applied (the old iOS variant silently dropped it),
addressing one of the API-parity gaps noted in callstack#4949.
fabriziocucci added a commit to fabriziocucci/react-native-paper that referenced this pull request May 21, 2026
Per maintainer feedback on callstack#4955, replace the iOS-specific Checkbox
implementation with the Android one (which is closer to the MD3 spec)
and inline the unified implementation directly into Checkbox.tsx.

Changes:
- Checkbox.tsx: inline what was the Android implementation; render the
  same MD3-compliant control on both platforms. Drop the Platform.OS
  dispatching.
- CheckboxAndroid.tsx, CheckboxIOS.tsx: deleted.
- Checkbox/index.ts: `Checkbox.Android` and `Checkbox.IOS` are kept
  as back-compat aliases of `Checkbox` itself, so existing imports
  keep working with no breaking change.
- CheckboxItem.tsx: drop the `mode`-based branching; always render
  `<Checkbox />`. The `mode` prop is kept and marked deprecated.
- src/index.tsx: `CheckboxAndroidProps` and `CheckboxIOSProps` now
  alias the unified `Props` from Checkbox.tsx (no breaking change).
- Snapshot tests updated: the renderer now uses the unified container
  (36x36 ripple) and MaterialCommunityIcon glyphs on both platforms.

`getSelectionControlIOSColor` in utils.ts is intentionally left in
place because RadioButtonIOS still depends on it. A similar unification
for RadioButton can follow in a separate PR.

As a side benefit, callers using `<Checkbox.IOS uncheckedColor=...>`
will now see the prop applied (the old iOS variant silently dropped it),
addressing one of the API-parity gaps noted in callstack#4949.
fabriziocucci added a commit to fabriziocucci/react-native-paper that referenced this pull request May 21, 2026
Per maintainer feedback on callstack#4955, drop the iOS-specific Checkbox renderer
and inline the unified MD3 implementation directly into Checkbox.tsx.
The same MaterialCommunityIcon-based control now renders on both
platforms.

Changes:
- Checkbox.tsx: inlines what was the Android implementation; renders the
  same control on both platforms. Drops the Platform.OS dispatching.
- CheckboxAndroid.tsx, CheckboxIOS.tsx: deleted.
- Checkbox/index.ts: `Checkbox.Android` and `Checkbox.IOS` are kept as
  back-compat aliases of `Checkbox` itself, so existing imports keep
  working with no breaking change.
- CheckboxItem.tsx: drops the `mode`-based branching; always renders
  `<Checkbox />`. The `mode` prop is kept and marked deprecated.
- src/index.tsx: `CheckboxAndroidProps` and `CheckboxIOSProps` now
  alias the unified `Props` from Checkbox.tsx (no breaking change).
- docs/docusaurus.config.js: removed entries for the now-deleted
  CheckboxAndroid and CheckboxIOS files.
- Snapshot tests updated: the renderer now uses the unified container
  (36x36 ripple) and MaterialCommunityIcon glyphs on both platforms.

`getSelectionControlIOSColor` in utils.ts is intentionally left in
place because RadioButtonIOS still depends on it. A similar unification
for RadioButton can follow in a separate PR.

As a side benefit, callers using `<Checkbox.IOS uncheckedColor=...>`
will now see the prop applied (the old iOS variant silently dropped it),
addressing one of the API-parity gaps noted in callstack#4949.
fabriziocucci added a commit to fabriziocucci/react-native-paper that referenced this pull request May 21, 2026
Per maintainer feedback on callstack#4955, drop the iOS-specific Checkbox renderer
and inline the unified MD3 implementation directly into Checkbox.tsx.
The same MaterialCommunityIcon-based control now renders on both
platforms.

Changes:
- Checkbox.tsx: inlines what was the Android implementation; renders the
  same control on both platforms. Drops the Platform.OS dispatching.
- CheckboxAndroid.tsx, CheckboxIOS.tsx: deleted.
- Checkbox/index.ts: `Checkbox.Android` and `Checkbox.IOS` are kept as
  back-compat aliases of `Checkbox` itself, so existing imports keep
  working with no breaking change.
- CheckboxItem.tsx: drops the `mode`-based branching; always renders
  `<Checkbox />`. The `mode` prop is kept and marked deprecated.
- src/index.tsx: `CheckboxAndroidProps` and `CheckboxIOSProps` now
  alias the unified `Props` from Checkbox.tsx (no breaking change).
- docs/docusaurus.config.js: removed entries for the now-deleted
  CheckboxAndroid and CheckboxIOS files.
- Snapshot tests updated: the renderer now uses the unified container
  (36x36 ripple) and MaterialCommunityIcon glyphs on both platforms.

`getSelectionControlIOSColor` in utils.ts is intentionally left in
place because RadioButtonIOS still depends on it. A similar unification
for RadioButton can follow in a separate PR.

As a side benefit, callers using `<Checkbox.IOS uncheckedColor=...>`
will now see the prop applied (the old iOS variant silently dropped it),
addressing one of the API-parity gaps noted in callstack#4949.
fabriziocucci added a commit to fabriziocucci/react-native-paper that referenced this pull request May 21, 2026
Per maintainer feedback on callstack#4955, drop the iOS-specific Checkbox renderer
and inline the unified MD3 implementation directly into Checkbox.tsx.
The same MaterialCommunityIcon-based control now renders on both
platforms.

Changes:
- Checkbox.tsx: inlines what was the Android implementation; renders the
  same control on both platforms. Drops the Platform.OS dispatching.
- CheckboxAndroid.tsx, CheckboxIOS.tsx: deleted.
- Checkbox/index.ts: `Checkbox.Android` and `Checkbox.IOS` are kept as
  back-compat aliases of `Checkbox` itself, so existing imports keep
  working with no breaking change.
- CheckboxItem.tsx: drops the `mode`-based branching; always renders
  `<Checkbox />`. The `mode` prop is kept and marked deprecated.
- src/index.tsx: `CheckboxAndroidProps` and `CheckboxIOSProps` now
  alias the unified `Props` from Checkbox.tsx (no breaking change).
- docs/docusaurus.config.js: removed entries for the now-deleted
  CheckboxAndroid and CheckboxIOS files.
- Snapshot tests updated: the renderer now uses the unified container
  (36x36 ripple) and MaterialCommunityIcon glyphs on both platforms.

`getSelectionControlIOSColor` in utils.ts is intentionally left in
place because RadioButtonIOS still depends on it. A similar unification
for RadioButton can follow in a separate PR.

As a side benefit, callers using `<Checkbox.IOS uncheckedColor=...>`
will now see the prop applied (the old iOS variant silently dropped it),
addressing one of the API-parity gaps noted in callstack#4949.
fabriziocucci added a commit to fabriziocucci/react-native-paper that referenced this pull request May 21, 2026
Per maintainer feedback on callstack#4955, drop the iOS-specific Checkbox renderer
and inline the unified MD3 implementation directly into Checkbox.tsx.
The same MaterialCommunityIcon-based control now renders on both
platforms.

Changes:
- Checkbox.tsx: inlines what was the Android implementation; renders the
  same control on both platforms. Drops the Platform.OS dispatching.
- CheckboxAndroid.tsx, CheckboxIOS.tsx: deleted.
- Checkbox/index.ts: `Checkbox.Android` and `Checkbox.IOS` are kept as
  back-compat aliases of `Checkbox` itself, so existing imports keep
  working with no breaking change.
- CheckboxItem.tsx: drops the `mode`-based branching; always renders
  `<Checkbox />`. The `mode` prop is kept and marked deprecated.
- src/index.tsx: `CheckboxAndroidProps` and `CheckboxIOSProps` now
  alias the unified `Props` from Checkbox.tsx (no breaking change).
- docs/docusaurus.config.js: removed entries for the now-deleted
  CheckboxAndroid and CheckboxIOS files.
- Snapshot tests updated: the renderer now uses the unified container
  (36x36 ripple) and MaterialCommunityIcon glyphs on both platforms.

`getSelectionControlIOSColor` in utils.ts is intentionally left in
place because RadioButtonIOS still depends on it. A similar unification
for RadioButton can follow in a separate PR.

As a side benefit, callers using `<Checkbox.IOS uncheckedColor=...>`
will now see the prop applied (the old iOS variant silently dropped it),
addressing one of the API-parity gaps noted in callstack#4949.
fabriziocucci added a commit to fabriziocucci/react-native-paper that referenced this pull request May 21, 2026
Per maintainer feedback on callstack#4955, drop the iOS-specific Checkbox renderer
and inline the unified MD3 implementation directly into Checkbox.tsx.
The same MaterialCommunityIcon-based control now renders on both
platforms.

Changes:
- Checkbox.tsx: inlines what was the Android implementation; renders the
  same control on both platforms. Drops the Platform.OS dispatching.
- CheckboxAndroid.tsx, CheckboxIOS.tsx: deleted.
- Checkbox/index.ts: `Checkbox.Android` and `Checkbox.IOS` are kept as
  back-compat aliases of `Checkbox` itself, so existing imports keep
  working with no breaking change.
- CheckboxItem.tsx: drops the `mode`-based branching; always renders
  `<Checkbox />`. The `mode` prop is kept and marked deprecated.
- src/index.tsx: `CheckboxAndroidProps` and `CheckboxIOSProps` now
  alias the unified `Props` from Checkbox.tsx (no breaking change).
- docs/docusaurus.config.js: removed entries for the now-deleted
  CheckboxAndroid and CheckboxIOS files.
- Snapshot tests updated: the renderer now uses the unified container
  (36x36 ripple) and MaterialCommunityIcon glyphs on both platforms.

`getSelectionControlIOSColor` in utils.ts is intentionally left in
place because RadioButtonIOS still depends on it. A similar unification
for RadioButton can follow in a separate PR.

As a side benefit, callers using `<Checkbox.IOS uncheckedColor=...>`
will now see the prop applied (the old iOS variant silently dropped it),
addressing one of the API-parity gaps noted in callstack#4949.
fabriziocucci added a commit to fabriziocucci/react-native-paper that referenced this pull request May 21, 2026
Per maintainer feedback on callstack#4955, drop the iOS-specific Checkbox renderer
and inline the unified MD3 implementation directly into Checkbox.tsx.
The same MaterialCommunityIcon-based control now renders on both
platforms.

Changes:
- Checkbox.tsx: inlines what was the Android implementation; renders the
  same control on both platforms. Drops the Platform.OS dispatching.
- CheckboxAndroid.tsx, CheckboxIOS.tsx: deleted.
- Checkbox/index.ts: `Checkbox.Android` and `Checkbox.IOS` are kept as
  back-compat aliases of `Checkbox` itself, so existing imports keep
  working with no breaking change.
- CheckboxItem.tsx: drops the `mode`-based branching; always renders
  `<Checkbox />`. The `mode` prop is kept and marked deprecated.
- src/index.tsx: `CheckboxAndroidProps` and `CheckboxIOSProps` now
  alias the unified `Props` from Checkbox.tsx (no breaking change).
- docs/docusaurus.config.js: removed entries for the now-deleted
  CheckboxAndroid and CheckboxIOS files.
- Snapshot tests updated: the renderer now uses the unified container
  (36x36 ripple) and MaterialCommunityIcon glyphs on both platforms.

`getSelectionControlIOSColor` in utils.ts is intentionally left in
place because RadioButtonIOS still depends on it. A similar unification
for RadioButton can follow in a separate PR.

As a side benefit, callers using `<Checkbox.IOS uncheckedColor=...>`
will now see the prop applied (the old iOS variant silently dropped it),
addressing one of the API-parity gaps noted in callstack#4949.
fabriziocucci added a commit to fabriziocucci/react-native-paper that referenced this pull request May 21, 2026
Per maintainer feedback on callstack#4955, drop the iOS-specific Checkbox renderer
and inline the unified MD3 implementation directly into Checkbox.tsx.
The same MaterialCommunityIcon-based control now renders on both
platforms.

Changes:
- Checkbox.tsx: inlines what was the Android implementation; renders the
  same control on both platforms. Drops the Platform.OS dispatching.
- CheckboxAndroid.tsx, CheckboxIOS.tsx: deleted.
- Checkbox/index.ts: `Checkbox.Android` and `Checkbox.IOS` are kept as
  back-compat aliases of `Checkbox` itself, so existing imports keep
  working with no breaking change.
- CheckboxItem.tsx: drops the `mode`-based branching; always renders
  `<Checkbox />`. The `mode` prop is kept and marked deprecated.
- src/index.tsx: `CheckboxAndroidProps` and `CheckboxIOSProps` now
  alias the unified `Props` from Checkbox.tsx (no breaking change).
- docs/docusaurus.config.js: removed entries for the now-deleted
  CheckboxAndroid and CheckboxIOS files.
- Snapshot tests updated: the renderer now uses the unified container
  (36x36 ripple) and MaterialCommunityIcon glyphs on both platforms.

`getSelectionControlIOSColor` in utils.ts is intentionally left in
place because RadioButtonIOS still depends on it. A similar unification
for RadioButton can follow in a separate PR.

As a side benefit, callers using `<Checkbox.IOS uncheckedColor=...>`
will now see the prop applied (the old iOS variant silently dropped it),
addressing one of the API-parity gaps noted in callstack#4949.
adrcotfas pushed a commit that referenced this pull request May 21, 2026
Per maintainer feedback on #4955, drop the iOS-specific Checkbox renderer
and inline the unified MD3 implementation directly into Checkbox.tsx.
The same MaterialCommunityIcon-based control now renders on both
platforms.

Changes:
- Checkbox.tsx: inlines what was the Android implementation; renders the
  same control on both platforms. Drops the Platform.OS dispatching.
- CheckboxAndroid.tsx, CheckboxIOS.tsx: deleted.
- Checkbox/index.ts: `Checkbox.Android` and `Checkbox.IOS` are kept as
  back-compat aliases of `Checkbox` itself, so existing imports keep
  working with no breaking change.
- CheckboxItem.tsx: drops the `mode`-based branching; always renders
  `<Checkbox />`. The `mode` prop is kept and marked deprecated.
- src/index.tsx: `CheckboxAndroidProps` and `CheckboxIOSProps` now
  alias the unified `Props` from Checkbox.tsx (no breaking change).
- docs/docusaurus.config.js: removed entries for the now-deleted
  CheckboxAndroid and CheckboxIOS files.
- Snapshot tests updated: the renderer now uses the unified container
  (36x36 ripple) and MaterialCommunityIcon glyphs on both platforms.

`getSelectionControlIOSColor` in utils.ts is intentionally left in
place because RadioButtonIOS still depends on it. A similar unification
for RadioButton can follow in a separate PR.

As a side benefit, callers using `<Checkbox.IOS uncheckedColor=...>`
will now see the prop applied (the old iOS variant silently dropped it),
addressing one of the API-parity gaps noted in #4949.
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.

4 participants