Skip to content

[pull] main from expo:main#831

Merged
pull[bot] merged 8 commits intocode:mainfrom
expo:main
May 4, 2026
Merged

[pull] main from expo:main#831
pull[bot] merged 8 commits intocode:mainfrom
expo:main

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented May 4, 2026

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

kitten and others added 8 commits May 4, 2026 18:04
…nsformer (#45348)

# Why

Resolves #44687

A typo in the Babel transformer here means that `BABEL_ENV` is
incorrectly restored to the incorrect value.

See:
https://github.com/facebook/metro/blob/5c4606f242b142f05efb082b2a5c8ea2445e0971/packages/metro-babel-transformer/src/index.js#L144
Regressed in #44366 / #44320

# How

- Fix inverted condition

# Test Plan

# 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)
- [ ] This diff will work correctly for `npx expo prebuild` & EAS Build
(eg: updated a module plugin).
- [ ] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)
# Why

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

# How

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

# Test Plan

<!--
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.
-->

- [ ] 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)
- [ ] This diff will work correctly for `npx expo prebuild` & EAS Build
(eg: updated a module plugin).
- [ ] 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>
# Summary

Changes within range:
facebook/metro@v0.84.3...v0.84.4

Upgrades to `@expo/metro@56.0.0-rc.2` / `metro@0.84.4`

Supersedes #45194

# Test Plan

<!--
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.
-->

- [ ] 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)
- [ ] This diff will work correctly for `npx expo prebuild` & EAS Build
(eg: updated a module plugin).
- [ ] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)
# Why

Adds a universal `TextInput` to `@expo/ui` that mirrors RN's
[TextInput](https://reactnative.dev/docs/textinput) API but routes to
SwiftUI TextField on iOS, Compose TextField on Android, and RN's
`TextInput` on web.

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

# How

Built on top of the existing `@expo/ui/swift-ui` and
`@expo/ui/jetpack-compose` `TextField` / `SecureField` components. Most
props pass through; a few needed new native plumbing (selection
observable, `onGeometryChange` / `onSizeChanged` modifiers, worklet
text/selection writes).

## API differences from RN's TextInput

A few things deliberately diverge.

### `value` is an `ObservableState`, not a string

We can assume that when you use a `value` prop, you want a controlled
input. Existing RN's TextInput is not truly controlled input as it
propagates events asynchronously which can lead to flickers. Also
mentioned [here](https://reactnative.dev/docs/textinput#value). So
currently only incentive to use Expo's universal TextInput is when you
need controlled TextInputs plus any extra features offered by TextField
on SwiftUI and Compose (via `modifiers` prop support). So we only
support `ObservableState` for `value` prop instead of `string`

```ts
const text = useNativeState('hello');
<TextInput value={text} />
```

### `selection` is also an `ObservableState`
```ts
const selection = useNativeState({ start: 0, end: 0 });
<TextInput value={text} selection={selection} />

// imperative
selection.value = { start: 0, end: 7 };
```


### `onChangeText` supports passing a worklet as well as regular
function.
Add the `'worklet'` directive and it runs synchronously on the UI
thread.

```tsx
<TextInput
  value={maskedPhone}
  onChangeText={(v) => {
    'worklet';
    const formatted = formatPhone(v);
    if (formatted !== v) maskedPhone.value = formatted;
  }}
/>
```


## Unsupported RN props


| Prop | Reason / workaround |
|---|---|
| `allowFontScaling` | Planned. iOS `.dynamicTypeSize(.large)`, Android
`LocalDensity(fontScale = 1f)`, web pass-through. |
| `clearButtonMode` (iOS) | SwiftUI doesn't expose it. Try `.searchable`
modifier or UIKit reach-in. |
| `contextMenuHidden` | iOS needs UIKit reach-in. Android could ship via
[`LocalTextToolbar`](https://developer.android.com/reference/kotlin/androidx/compose/ui/platform/LocalTextToolbar).
|
| `dataDetectorTypes` (iOS) | No SwiftUI API |
| `disableFullscreenUI` (Android) | Compose's `KeyboardOptions` doesn't
surface it. |
| `disableKeyboardShortcuts` (iOS) | Hides iPad keyboard's system
shortcut bar. UIKit-only. |
| `enablesReturnKeyAutomatically` (iOS) | No SwiftUI API |
| `importantForAutofill` (Android) | Already implicit via
`autoComplete`. |
| `inlineImageLeft` / `inlineImagePadding` (Android) | Use a
`leadingIcon` slot from `@expo/ui/jetpack-compose`'s `TextField`. |
| `inputAccessoryViewID` / `inputAccessoryViewButtonLabel` (iOS) |
Future: `keyboardToolbar` slot via `.toolbar(placement: .keyboard)`. |
| `keyboardAppearance` (iOS) | UIKit reach-in.  |
| `lineBreakStrategyIOS` | No SwiftUI TextField API |
| `lineBreakModeIOS` | No SwiftUI TextField API |
| `maxFontSizeMultiplier` | Planned. Same wiring as `allowFontScaling`,
numeric cap. |
| `onChange` | Use `onChangeText`. |
| `onEndEditing` | Use `onBlur` or `onSubmitEditing`. |
| `onKeyPress` | Compose has no per-keystroke event for soft keyboards;
SwiftUI has nothing. Diff successive `onChangeText` values for
backspace-on-empty. |
| `onLayout` | Use `Host`'s `onLayout`. |
| `onPressIn` / `onPressOut` | Tap events on `Host`. |
| `onScroll` | TODO |
| `passwordRules` (iOS) | No SwiftUI TextField API |
| `rejectResponderTermination` (iOS) | No SwiftUI API |
| `returnKeyLabel` (Android) | No API in Compose. Use `returnKeyType`. |
| `scrollEnabled` | No clean SwiftUI/Compose API. TODO: Analyse further
|
| `showSoftInputOnFocus` | Planned (Android via Compose 1.7's
`KeyboardOptions.showKeyboardOnFocus`). iOS needs UIKit reach-in. |
| `smartInsertDelete` (iOS) | UIKit smart-whitespace handling. Default
is correct. |
| `spellCheck` (iOS) | `autoCorrect={false}` covers it cross-platform. |
| `submitBehavior` | No SwiftUI/Compose clean API. TODO: Might need
custom native handling. Plan next |
| `textBreakStrategy` (Android) | No Compose API |



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

# Test Plan

Added universal TextInput in NCL.


https://github.com/user-attachments/assets/ce147ada-4e59-448a-97a9-ba25643df159




<!--
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)
…untime provider (expo-ui support) (#45026)

## Why

`ExpoModulesWorklets` lived inside expo-modules-core and used `#if
WORKLETS_ENABLED` to gate every worklets::* C++ reference at compile
time. Worked for source builds but is incompatible with shipping a
precompiled xcframework — the binary would be frozen to one branch of
the gate.

Goal: let `ExpoModulesWorklets` ship as a precompiled xcframework, keep
the public Swift/ObjC API unchanged, and degrade gracefully when
`react-native-worklets` isn't installed (so @expo/ui and other pods that
depend on it can also be precompiled).

## How

Three pods carved from packages/expo-modules-core:

### ExpoModulesCore 

no changes

### ExpoModulesWorklets:

public API: Worklet, WorkletRuntime, JavaScriptSerializable,
Serializable. Zero worklets::* references — talks to a runtime-injected
provider via EXWorkletsProvider ObjC protocol.

### ExpoModulesWorkletsAdapter

**Source-only**

Holds every worklets::* reference (ExpoWorkletsBridgeProvider.{h,mm}).
Depends on RNWorklets. Auto-linked only when `RNWorklets` is present in
the Podfile.

Also added support for a force `sourceOnly` flag in sim.config.json

## Test plan

- [x] `apps/bare-expo` 
- `react-native-worklets` installed, run `pod install`, build, check
`WorkletsTester`.
- [x] `apps/minimal-tester` without worklets — adapter empty; main pod
links with zero `worklets::*` references; `expo-ui` builds.
- [x] `et prebuild expo-modules-core -f Debug --clean` — produces both
xcframeworks.
- [x] `et prebuild @expo/ui -f Debug --clean` against the new worklets
product — green.
- [x] iOS precompiled-xcframeworks smoke test on CI.
…moved in the future (#45339)

# Why

React Navigation exports internal logic, which we may not want to
officially support. Deprecating exports, does not mean we need to remove
it, but makes the removal easier in the future.

# How

1. Deprecate most of react-navigation exports. 
2. Add router alternatives to the ones we want to support

# Test Plan

CI

# Checklist

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

- [ ] 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)
- [ ] This diff will work correctly for `npx expo prebuild` & EAS Build
(eg: updated a module plugin).
- [ ] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)
…5134)

# Why

<!--
Please describe the motivation for this PR, and link to relevant GitHub
issues, forums posts, or feature requests.
-->
The `expo-updates` SDK reference table lists the default for
`updates.checkAutomatically` as `ALWAYS`, but the linked app config
reference (`/versions/latest/config/app/#checkautomatically`) documents
the enum as `ON_LOAD | ON_ERROR_RECOVERY | WIFI_ONLY | NEVER` with
`ON_LOAD` as the default. `ALWAYS` is the internal native value that
maps to `ON_LOAD`; the public app-config name is `ON_LOAD`, so the SDK
reference should use it for consistency.

Affected pages:
- https://docs.expo.dev/versions/latest/sdk/updates/
- https://docs.expo.dev/versions/latest/config/app/#checkautomatically

# How
- docs/pages/versions/unversioned/sdk/updates.mdx
- docs/pages/versions/v55.0.0/sdk/updates.mdx

<!--
How did you build this feature or fix this bug and why?
-->
Changed the `Default` cell for `updates.checkAutomatically` from ``
`ALWAYS` `` to `` `ON_LOAD` `` in:

# Test Plan

<!--
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.
-->
Ran the docs site locally (`pnpm dev` in `docs/`) and confirmed the
configuration table on `/versions/latest/sdk/updates/` now renders
`ON_LOAD` as the default.

# Checklist

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

- [ ] 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)
- [ ] 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)
@pull pull Bot locked and limited conversation to collaborators May 4, 2026
@pull pull Bot added the ⤵️ pull label May 4, 2026
@pull pull Bot merged commit 95c8d93 into code:main May 4, 2026
17 of 24 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants