Skip to content

feat: refactor icon button component - #5103

Open
alpharius-ck wants to merge 6 commits into
mainfrom
feat/refactor-icon-button-component
Open

alpharius-ck wants to merge 6 commits into
mainfrom
feat/refactor-icon-button-component

Conversation

@alpharius-ck

Copy link
Copy Markdown

Motivation

IconButton in v6 still used the older Material 3 API: a numeric size, contained / contained-tonal modes, and a single selected-color path. That does not match the current M3 Expressive icon button spec (or the androidx 14.1.0 tokens), and it is out of step with components that were already modernized (TextInput, Switch, Checkbox, FAB).

This change brings IconButton onto that spec: the XS–XL size scale, narrow / default / wide widths, round and square shapes with press and toggle morph, standard / filled / tonal / outlined color styles (including a distinct toggle-OFF set), and disabled filled/tonal container opacity of 0.10. Tokens live with the component and reuse the theme shape, color, and motion systems so the example app and generated docs stay aligned.

Related issue

https://app.notion.com/p/callstack/Modernize-IconButton-to-Material-3-Expressive-3ac5d027c0f880fcb083e5a909d4d82b?source=copy_link

Test plan

Screenshot 2026-09-03 at 11 36 06 Screenshot 2026-09-03 at 11 58 43

# Conflicts:
#	src/components/IconButton/IconButton.tsx
#	src/components/IconButton/utils.ts
#	src/components/TextInput/TextInputIcon.tsx
alpharius-ck and others added 2 commits September 8, 2026 10:53
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@satya164
satya164 requested a balanced review from Copilot September 15, 2026 20:32

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Co-authored-by: Cursor <cursoragent@cursor.com>
@satya164

Copy link
Copy Markdown
Member

Review by Claude

iOS

  1. The toggle shape ends up inverted after a quick tap.
    Steps: open the Icon Button example, tap the first Playground button once, then tap it again.
    What happens: the selected button stays round. The unselected button turns square.
    What should happen: a round button turns square when selected and goes back to round when unselected, as it does on web.
    iOS: toggle shape after a quick tap
    (via Claude, verify if it makes sense)

  2. Removing the 6dp margin from IconButton moves the icon buttons in Appbar, Searchbar and DataTable.Pagination.
    Steps: open the Appbar, Searchbar and Data Table examples and compare with main.
    What happens: the back icon and the title move toward the edge, the trailing actions and the bottom bar actions touch each other, the Searchbar icon and text move left, and the pagination arrows sit closer together.
    What should happen: these components keep their spacing, or get the spacing from the Material spec.
    iOS: Appbar on main and on this PR
    iOS: Searchbar on main and on this PR
    iOS: DataTable pagination on main and on this PR
    (via Claude, verify if it makes sense)

Android

  1. The same toggle shape bug as on iOS.
    Steps: open the Icon Button example, tap the first Playground button once, then tap it again.
    What happens: the selected button stays round. The unselected button turns square.
    What should happen: a round button turns square when selected and goes back to round when unselected.
    Android: toggle shape after a quick tap
    (via Claude, verify if it makes sense)

@satya164 satya164 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.

Review by Claude

  • The migration guide (docs/6.x/docs/guides/migration.md) has no IconButton section for these breaking changes: mode="contained" to "filled" and "contained-tonal" to "tonal", the numeric size replaced by named sizes, size removed from Appbar.Action and Appbar.BackAction, selected={false} now picking the toggle-off colors (for example filled turns surfaceContainer instead of primary), the removed 6dp margin, and Card.Title right props that can no longer be spread into IconButton. JavaScript users who still pass size={24} get a crash, because IconButtonTokens.sizes[24] is undefined and getDimensions reads spec.widths. Please add before and after snippets for each.

See the inline comments for the rest. (via Claude, verify if it makes sense)

Comment thread src/components/IconButton/IconButton.tsx
Comment thread src/components/IconButton/IconButton.tsx
Comment thread src/components/IconButton/IconButton.tsx
Comment thread src/components/IconButton/IconButton.tsx
Comment thread src/components/IconButton/IconButton.tsx
Comment thread src/components/IconButton/IconButton.tsx
Comment thread example/src/Examples/IconButtonExample.tsx
Comment thread example/src/Examples/IconButtonExample.tsx
Comment thread package.json
Comment thread docs/src/data/screenshots.ts

This branch has not been deployed

No deployments
Sign up for free to 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