Skip to content

[pull] main from expo:main#748

Merged
pull[bot] merged 6 commits intocode:mainfrom
expo:main
Apr 6, 2026
Merged

[pull] main from expo:main#748
pull[bot] merged 6 commits intocode:mainfrom
expo:main

Conversation

@pull
Copy link
Copy Markdown

@pull pull bot commented Apr 6, 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 : )

Kudo and others added 6 commits April 6, 2026 17:56
# Why

improve jetpack-compose Children performance

# How

use `key(child)` than the default index

# Test Plan

NCL

# Checklist

- [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)
# Why

fixed the other error: `java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.`

# How

remove parent first

# Test Plan

```jsx
import { Host, LazyColumn, RNHostView, Text } from '@expo/ui/jetpack-compose';
import { useState } from 'react';
import { Button, View } from 'react-native';

export default function CrashTest() {
  const [show, setShow] = useState(true);

  return (
    <View style={{ flex: 1, paddingTop: 80 }}>
      <Button
        title={show ? 'Hide middle item' : 'Show middle item'}
        onPress={() => setShow((v) => !v)}
      />
      <Host style={{ flex: 1 }}>
        <LazyColumn>
          <Text>Item A</Text>
          {show && <Text>Item B (conditional)</Text>}
          <RNHostView matchContents>
            <View style={{ padding: 20, backgroundColor: '#E3F2FD' }}>
              <Button title="I'm an RN View in RNHostView" onPress={() => {}} />
            </View>
          </RNHostView>
        </LazyColumn>
      </Host>
    </View>
  );
}
```

# Checklist

- [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)
# Why

This PR replaces `expo_status_bar_visibility` /
`expo_navigation_bar_visibility` (strings stored in `strings.xml`) with
new theme attributes: `expoStatusBarHidden` and
`expoNavigationBarHidden` (booleans stored in `styles.xml`).

The rationale is the following:

- This follows the same `expo*` attribute pattern used by
`expo-image-picker`
- It will not affect users using CNG
- If you don't use CNG, currently you have to update both `styles.xml`
(to set `android:navigationBarColor`,
`android:enforceNavigationBarContrast`,
`android:windowLightNavigationBar`…) and set `<string
name="expo_navigation_bar_visibility"
translatable="false">hidden</string>` in a separate file, `strings.xml`
- which is weird. By switching to a boolean theme attribute, its value
can be set in `styles.xml` alongside other Android theme attributes

# How

- Deleted `strings.xml` resource files from both `expo-status-bar` and
`expo-navigation-bar` packages
- Added `attrs.xml` resource files declaring `expoStatusBarHidden` and
`expoNavigationBarHidden` as boolean attributes
- Updated the Kotlin `ReactActivityLifecycleListener` implementations to
read the boolean attribute from the theme using `obtainStyledAttributes`
- Updated the config plugins (`withStatusBar.ts`,
`withNavigationBar.ts`) to write the value into `styles.xml` via
`assignStylesValue`
- Updated existing documentation

# Test Plan

- Ran `npx expo prebuild` on a bare app with `expo-status-bar` and
`expo-navigation-bar` configured with `hidden: true`
- Verified that the generated `styles.xml` contains `<item
name="expoStatusBarHidden">true</item>` and `<item
name="expoNavigationBarHidden">true</item>` under the app theme
- Built and ran the app on an Android device, confirmed both bars are
hidden on startup

# 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)
…omponents (#44373)

# Why

Add Material3
[Tooltip](https://developer.android.com/reference/kotlin/androidx/compose/material3/TooltipBox.composable)
support for Jetpack Compose matching the native API.

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

# How

- `TooltipBox` - wraps anchor content, shows tooltip on
long-press/hover. Supports `isPersistent`, `hasAction`,
`enableUserInput`, `focusable`. Exposes `show()`/`dismiss()` via ref.
- `PlainTooltip` - simple tooltip with text content. Accepts
`containerColor`, `contentColor`, modifiers.
- `RichTooltip` - detailed tooltip with `.Title`, `.Text`, `.Action`
slots. Accepts color props and modifiers.
- `PlainTooltipView`/`RichTooltipView` are class-based views so
`TooltipBoxView` can detect them by type via `findChildOfType`.
  - Added docs for the same


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

  # Test Plan

  - Open native-component-list → Expo UI → Tooltip screen on Android.
  - Long-press buttons to trigger plain and rich tooltips.
  - Test programmatic show/dismiss via ref.



https://github.com/user-attachments/assets/6d6d6682-3afc-42c9-8e4a-0c80f5cabca6



<!--
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>
…d < Q (#44477)

# Why

On Android < Q (API 29), `android:enforceNavigationBarContrast` is not
available. This means the navigation bar button style is not
automatically adjusted for contrast, which can result in invisible
buttons ("light on light" or "dark on dark").

Additionally, `isAppearanceLightNavigationBars` is not available below
Android O (API 26), so `setStyle` should no-op entirely on those
devices.

# How

- Added an early return for Android < O, where
`isAppearanceLightNavigationBars` is not supported.
- On Android O–P (API 26–28), we now set an explicit navigation bar
color using the same light/dark scrim colors used by the platform on API
29+. This ensures proper contrast between the bar background and its
buttons.

# Test Plan

- Run on an Android < O emulator/device, call
`NavigationBar.setStyle("dark")`, verify it no-ops.
- Run on an Android O–P device, call `NavigationBar.setStyle("dark")` /
`NavigationBar.setStyle("light")`, verify the navigation bar color
changes to provide proper contrast.
- Run on an Android >= Q device, call `NavigationBar.setStyle("dark")` /
`NavigationBar.setStyle("light")`, verify the style updates correctly as
before.

# Checklist

- [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)

# Screenshots

## Current behavior

<img width="514" height="962" alt="Android 9 - style= light"
src="https://github.com/user-attachments/assets/723d285b-46e1-48a1-bba3-49c2f67238a2"
/>
@pull pull bot locked and limited conversation to collaborators Apr 6, 2026
@pull pull bot added the ⤵️ pull label Apr 6, 2026
@pull pull bot merged commit 6afcd95 into code:main Apr 6, 2026
24 of 31 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.

4 participants