Skip to content

[ui][ios] - Match Button API with SwiftUI#41617

Merged
intergalacticspacehighway merged 13 commits intomainfrom
button-changes
Dec 16, 2025
Merged

[ui][ios] - Match Button API with SwiftUI#41617
intergalacticspacehighway merged 13 commits intomainfrom
button-changes

Conversation

@intergalacticspacehighway
Copy link
Copy Markdown
Contributor

@intergalacticspacehighway intergalacticspacehighway commented Dec 13, 2025

Why

Matches Button's API with SwiftUI and adds missing modifiers. This is a breaking change but refactoring the component to new changes should be easy. This simplifies a lot of conditional code on native side. It will be easier to add features/debug.

How

Updated the API, examples and docs.

Breaking changes

  • Replaced string support in children prop with a label prop. The reason for this is that when children is used for string it requires call to special method getTextFromChildren, which tries to iterate the children and checks if it's a string. This always felt a bit awkward. Introducing label prop removes this requirement and makes our API match with the SwiftUI API since SwiftUI's Button accepts label argument in the constructor for string labels.
  • Removed support for icon only buttons. SwiftUI Button's documentation states that one should pass label and use labelStyle with iconOnly for icon buttons. Passing label is required in SwiftUI's API as it is a required for accessibility/screen readers. So we follow the same approach with our API. Also, added documentation to create icon only buttons.
  • Removed support for color, controlSize and variant props. Added modifiers for each of these.

Test Plan

Tested all the Button usage screens by updating to the new changes.

Checklist

@github-actions
Copy link
Copy Markdown
Contributor

Subscribed to pull request

File Patterns Mentions
docs/** @amandeepmittal
packages/expo-ui/** @aleqsio, @behenate, @douglowder

Generated by CodeMention

@expo-bot expo-bot added the bot: suggestions ExpoBot has some suggestions label Dec 13, 2025
@expo-bot expo-bot added bot: passed checks ExpoBot has nothing to complain about and removed bot: suggestions ExpoBot has some suggestions labels Dec 13, 2025
@expo-bot
Copy link
Copy Markdown
Collaborator

expo-bot commented Dec 15, 2025

The Pull Request introduced fingerprint changes against the base commit: 98d06cb

Fingerprint diff
[
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo-ui/ios",
      "reasons": [
        "expoAutolinkingIos"
      ],
      "hash": "cd35c3281d0996f9152955f937c9295467960df5"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo-ui/ios",
      "reasons": [
        "expoAutolinkingIos"
      ],
      "hash": "0a23ff7b0669e6023fee45c2ebd6d067775908b2"
    }
  }
]

Generated by PR labeler 🤖

@intergalacticspacehighway intergalacticspacehighway marked this pull request as ready for review December 15, 2025 08:12
Comment thread docs/pages/versions/unversioned/sdk/ui/swift-ui/button.mdx Outdated
You can pass custom components as `children` for more complex button label content.

```tsx CustomContentExample.tsx
import { Host, Button, VStack, Image, Text } from '@expo/ui/swift-ui';
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.

Suggested change
import { Host, Button, VStack, Image, Text } from '@expo/ui/swift-ui';
import { Host, Button, VStack } from '@expo/ui/swift-ui';
import { Image } from 'expo-image';
import { Text } from 'react-native';

I suppose we don't have Image and Text components in @expo/ui/swift-ui?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

yeah we do! Image supports systemImage and we also have Text. But they do not have documentation yet 😅

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.

Thanks for the clarification!

func body(content: Content) -> some View {
content.controlSize(size.toNativeControlSize())
}
} No newline at end of file
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.

Suggested change
}
}

EOF

@intergalacticspacehighway intergalacticspacehighway merged commit c8bd541 into main Dec 16, 2025
14 checks passed
@intergalacticspacehighway intergalacticspacehighway deleted the button-changes branch December 16, 2025 08:11
aleqsio pushed a commit that referenced this pull request Dec 22, 2025
# Why

Matches Button's API with SwiftUI and adds missing modifiers. This is a
breaking change but refactoring the component to new changes should be
easy. This simplifies a lot of conditional code on native side. It will
be easier to add features/debug.

<!--
Please describe the motivation for this PR, and link to relevant GitHub
issues, forums posts, or feature requests.
-->

# How

Updated the API, examples and docs.

### Breaking changes
- Replaced string support in `children` prop with a `label` prop. The
reason for this is that when `children` is used for string it requires
call to special method `getTextFromChildren`, which tries to iterate the
children and checks if it's a string. This always felt a bit awkward.
Introducing `label` prop removes this requirement and makes our API
match with the [SwiftUI
API](https://developer.apple.com/documentation/swiftui/button/init(_:action:))
since SwiftUI's Button accepts label argument in the constructor for
string labels.
- Removed support for icon only buttons. SwiftUI Button's documentation
states that one should pass label and use `labelStyle` with `iconOnly`
for icon buttons. Passing label is required in SwiftUI's API as it is a
required for accessibility/screen readers. So we follow the same
approach with our API. Also, added documentation to create icon only
buttons.
- Removed support for `color`, `controlSize` and `variant` props. Added
modifiers for each of these.

<!--
How did you build this feature or fix this bug and why?
-->

# Test Plan

Tested all the Button usage screens by updating to the new changes.

<!--
Please describe how you tested this change and how a reviewer could
reproduce your test, especially if this PR does not include automated
tests! If possible, please also provide terminal output and/or
screenshots demonstrating your test/reproduction.
-->

# Checklist

<!--
Please check the appropriate items below if they apply to your diff.
-->

- [x] I added a `changelog.md` entry and rebuilt the package sources
according to [this short
guide](https://github.com/expo/expo/blob/main/CONTRIBUTING.md#-before-submitting)
- [x] This diff will work correctly for `npx expo prebuild` & EAS Build
(eg: updated a module plugin).
- [x] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)

---------

Co-authored-by: Aman Mittal <amandeepmittal@live.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot: fingerprint changed bot: passed checks ExpoBot has nothing to complain about

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants