Skip to content

fix(react-native): migrate Button off @gluestack-ui/button - #1501

Merged
jordmccord merged 2 commits into
hearth-react-native-v1from
jordmccord-uwds-4799
Aug 6, 2026
Merged

fix(react-native): migrate Button off @gluestack-ui/button#1501
jordmccord merged 2 commits into
hearth-react-native-v1from
jordmccord-uwds-4799

Conversation

@jordmccord

Copy link
Copy Markdown
Collaborator

Summary

  • UWDS-4799: removes @gluestack-ui/button from Button, IconButton, UnstyledIconButton, and ToggleButton (all previously wired through the shared createButton factory).
  • createButton provided pressed-state tracking (via @react-native-aria/interactions), unused hover/focus/focus-visible aggregation, and a web-oriented role="button" default. Replaced with a plain Pressable + useState press tracker (composed with any consumer onPressIn/onPressOut) and an explicit accessibilityRole="button" default.
  • ButtonGroup's reversed prop (child reordering) is reimplemented as a plain array reversal, since gluestack's Group factory was the only thing consuming it.
  • No visual, prop, or behavioural change for consumers.
  • Added a baseline play-function test to Button.stories.tsx > Playground (previously untested) and a States story covering default/disabled/loading, per this epic's baseline-then-migrate convention. IconButton/UnstyledIconButton/ToggleButton's existing baseline tests are unchanged and re-verified against the migrated implementation.

Test plan

  • pnpm typecheck — clean
  • pnpm lint (scoped to Button-family) — clean
  • pnpm checks (repo root) — 10/10 tasks pass
  • Manually verified in Storybook: Button/IconButton/UnstyledIconButton/ToggleButton Playground + States stories render correctly (default, disabled, loading, pressed) and all interaction-test assertions (role, press, onPress firing, disabled/aria-disabled) pass
  • @gluestack-ui/button removed from package.json, no remaining source references
  • Changeset added (🧹 [HOUSEKEEPING], patch)

Note: while verifying, found a pre-existing, unrelated flake where some interaction tests intermittently fail on a stray ReanimatedError from the global BottomSheetModalProvider decorator in .storybook/preview.tsx (every real assertion still passes). Filed as UWDS-4922 rather than fixed here, since it's unrelated to this migration.

🤖 Generated with Claude Code

…ggleButton off @gluestack-ui/button

Replaces createButton's Pressable factory (pressed-state tracking via
@react-native-aria/interactions, unused hover/focus aggregation, and a
role="button" default) with plain Pressable + useState press tracking
and an explicit accessibilityRole="button" default. Adds a baseline
play-function test to Button's previously-untested Playground story.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 6, 2026 12:17
@linear-code

linear-code Bot commented Aug 6, 2026

Copy link
Copy Markdown

UWDS-4799

@changeset-bot

changeset-bot Bot commented Aug 6, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: cf43234

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@utilitywarehouse/hearth-react-native Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

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

Pull request overview

Migrates the React Native Button family (Button, IconButton, UnstyledIconButton, ToggleButton) off @gluestack-ui/button by removing the shared createButton factory usage and implementing the needed behavior directly with React Native Pressable, while also updating Storybook interaction coverage and removing the dependency from the package.

Changes:

  • Replace createButton usage with direct Pressable rendering + internal pressed-state tracking via onPressIn/onPressOut and useState.
  • Reimplement ButtonGroup’s reversed behavior by reversing the rendered children array.
  • Remove @gluestack-ui/button from dependencies/lockfile and add/update Storybook play interaction tests and a changeset.

Reviewed changes

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

Show a summary per file
File Description
pnpm-lock.yaml Removes @gluestack-ui/button (and related snapshot entries) from the lockfile.
packages/react-native/package.json Drops @gluestack-ui/button dependency from @utilitywarehouse/hearth-react-native.
packages/react-native/src/components/Button/Button.tsx Stops using createButton; renders ButtonRoot directly and re-exports subcomponents directly.
packages/react-native/src/components/Button/ButtonRoot.tsx Adds internal pressed tracking and sets Pressable defaults (accessibilityRole, disabled).
packages/react-native/src/components/Button/ButtonGroup.tsx Reimplements reversed by reversing children ordering before rendering ButtonGroupRoot.
packages/react-native/src/components/Button/Button.stories.tsx Adds play test for Playground and introduces a States story with interaction assertions.
packages/react-native/src/components/IconButton/IconButton.tsx Removes createButton wrapper; uses IconButtonRootComponent directly.
packages/react-native/src/components/IconButton/IconButtonRoot.tsx Adds internal pressed tracking and ensures Pressable has accessibilityRole and disabled.
packages/react-native/src/components/IconButton/IconButton.stories.tsx Updates interaction-test comments to reflect direct Pressable usage.
packages/react-native/src/components/UnstyledIconButton/UnstyledIconButton.tsx Removes createButton wrapper; uses root/icon/spinner components directly.
packages/react-native/src/components/UnstyledIconButton/UnstyledIconButtonRoot.tsx Adds internal pressed tracking and passes disabled to Pressable.
packages/react-native/src/components/UnstyledIconButton/UnstyledIconButton.stories.tsx Updates interaction-test comments to reflect direct Pressable usage.
packages/react-native/src/components/ToggleButton/ToggleButton.tsx Removes createButton wrapper; renders ToggleButtonRoot directly.
packages/react-native/src/components/ToggleButton/ToggleButtonRoot.tsx Adds internal pressed tracking and explicit default accessibilityRole="button".
.changeset/button-remove-gluestack.md Adds a patch changeset documenting the migration off @gluestack-ui/button.
Files not reviewed (1)
  • pnpm-lock.yaml: Generated file

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

Comment thread packages/react-native/src/components/ToggleButton/ToggleButtonRoot.tsx Outdated
…puted disabled/selected

Copilot review on #1501: ToggleButtonRoot and UnstyledIconButtonRoot spread
props.accessibilityState after the computed disabled/selected value, letting a
consumer-supplied accessibilityState silently override the real state exposed
to assistive tech. Swap the spread order so the computed value always wins.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@jordmccord
jordmccord merged commit 51ec348 into hearth-react-native-v1 Aug 6, 2026
9 of 12 checks passed
@jordmccord
jordmccord deleted the jordmccord-uwds-4799 branch August 6, 2026 12:40
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.

2 participants