Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions apps/bare-expo/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { AppMetricsRoot } from 'expo-observe';
import * as Splashscreen from 'expo-splash-screen';
import React from 'react';
import * as DevMenu from 'expo-dev-menu';
import ExpoObserve from 'expo-observe';

import MainNavigator, { optionalRequire } from './MainNavigator';

Expand Down Expand Up @@ -65,6 +66,10 @@ function useLoaded() {
return isLoaded;
}

ExpoObserve.configure({
dispatchingEnabled: true,
});

export default function Main() {
React.useEffect(() => {
try {
Expand Down
6 changes: 5 additions & 1 deletion apps/bare-expo/MainNavigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,11 @@ export default function MainNavigator() {
.catch(console.error)
.finally(() => {
setIsReady(true);
AppMetrics.markInteractive();
AppMetrics.markInteractive({
params: {
theme: themeName,
},
});
});
}, [isReady]);

Expand Down
3 changes: 0 additions & 3 deletions apps/bare-expo/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,6 @@
"extra": {
"eas": {
"projectId": "2c28de10-a2cd-11e6-b8ce-59d1587e6774",
"observe": {
"enableInDebug": true
}
}
},
"runtimeVersion": "1.0.0",
Expand Down
6 changes: 3 additions & 3 deletions apps/bare-expo/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4012,7 +4012,7 @@ SPEC CHECKSUMS:
EXUpdates: a0f980531cbcf45906b2489febd4e11a5895f332
EXUpdatesInterface: 5ab8c3e8018ef533a132b9327af5b2a1926dd299
FBLazyVector: 26fd21c75314e101f280d401e97f27d54f3f7064
hermes-engine: e1ae00897676f600a9439d408b42f8c8ba5dbc24
hermes-engine: 725fd85144e1348879039099a6be950c471a4f2c
libavif: 5f8e715bea24debec477006f21ef9e95432e254d
libdav1d: 23581a4d8ec811ff171ed5e2e05cd27bad64c39f
libwebp: 02b23773aedb6ff1fd38cec7a77b81414c6842a8
Expand All @@ -4030,7 +4030,7 @@ SPEC CHECKSUMS:
React: 13cf8451582adb1bb324306e1893b91d1cba28c6
React-callinvoker: 91e6a605826b684ad2e623811253b4d0c4196bef
React-Core: 46818de5f211b2a2759ac823b591af8a0a95c2c1
React-Core-prebuilt: 1e81ce373ae6d21c61a961e1be02e77633de3007
React-Core-prebuilt: 4016009b4cc1d669b1a2369a5d707cdb39fa12ef
React-CoreModules: a6a37afee48d4a31ab398640b0795462647d5c67
React-cxxreact: 2ec3e2f7a8ae9303460d4ba94cde183ea90d64cd
React-debug: 0d21117b897ce0359c9d2c9dfe952f237476a14a
Expand Down Expand Up @@ -4100,7 +4100,7 @@ SPEC CHECKSUMS:
ReactAppDependencyProvider: 22e2265d86a4e871e5e858f4e7ef1c8d01103680
ReactCodegen: f564776e1b15423920d439de1965d2000433dbd2
ReactCommon: a804bb8d1dcf3ecdec3a77eb8bba19b7863bbbdb
ReactNativeDependencies: ceedcc3a6ff166bea3c3816a22f58c478ffad807
ReactNativeDependencies: a24dd0e4b4318c05556b4b7bb144738f83775e22
RNCAsyncStorage: 2ad919e88b8bc2cd80e8697ce66d04d006743283
RNCMaskedView: eb2b2e538afa907f05a5848a1a1ac26092e6fec9
RNCPicker: d74667bdfc08ed389a2a277d95b8faf2349290a9
Expand Down
8 changes: 4 additions & 4 deletions apps/expo-go/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4636,7 +4636,7 @@ SPEC CHECKSUMS:
ExpoMailComposer: edd4f46a26ea55ff0e3a83ef0192e79f647911c8
ExpoMediaLibrary: 2fbddcb06042f43076cf5e495e8237ec2ab95726
ExpoMeshGradient: 93cf09380e6d86cd7a525da26dfddab2620a8421
ExpoModulesCore: 936a4fb73792d8c8bc861d57522539c35fc36e40
ExpoModulesCore: 13bc5b9a2fefacfab477b20600dc57821aa4a200
ExpoModulesJSI: 793687b04cbaa73ee8548bfdbcfba85954d1b2b5
ExpoModulesTestCore: 62ce59e8c8162b449e65467e0421240256ba6732
ExpoModulesWorklets: 3a4d6451e29822c01c397da92be1f962a0f870fe
Expand All @@ -4661,7 +4661,7 @@ SPEC CHECKSUMS:
ExpoVideoThumbnails: 2340f0b7f599c9ce6ba49a885f783de919cf4dd3
ExpoWebBrowser: b65b3921741b51c5513e2a369f59c37076987d9b
EXStructuredHeaders: e25ac67c966d3795153dfdb40bfd3b999df18929
EXUpdates: 33cea909186babc6befefeed3596a82b6c1d63de
EXUpdates: 56ce06b32bea90efb1e4c6b28d73e4cfb472b71b
EXUpdatesInterface: 5ab8c3e8018ef533a132b9327af5b2a1926dd299
fast_float: b32c788ed9c6a8c584d114d0047beda9664e7cc6
FBLazyVector: 4cd65993d9ef677523093deeb7d8710f39fb9ed7
Expand All @@ -4674,7 +4674,7 @@ SPEC CHECKSUMS:
FirebaseRemoteConfigInterop: 85bdce8babed7814816496bb6f082bc05b0a45e1
FirebaseSessions: f5c6bfeb66a7202deaf33352017bb6365e395820
fmt: 530618a01105dae0fa3a2f27c81ae11fa8f67eac
glog: e56ede4028c4b7418e6b1195a36b1656bb35e225
glog: 5683914934d5b6e4240e497e0f4a3b42d1854183
GoogleAppMeasurement: 8a82b93a6400c8e6551c0bcd66a9177f2e067aed
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1
Expand All @@ -4690,7 +4690,7 @@ SPEC CHECKSUMS:
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
PromisesSwift: 9d77319bbe72ebf6d872900551f7eeba9bce2851
Quick: 83e25bf349dd84f894b024f48033274512d6129b
RCT-Folly: 36c4f904fb6cd0219dcb76b94e9502d2a72fab0b
RCT-Folly: 121436bcc4611f6bde5c09bf35f0a7a82cef1969
RCTDeprecation: 5c945c659e2d68c1428f4a732c83198a4ad6a659
RCTRequired: c98eb09689f6a2a2c75f6fd419fa94fe71a672c9
RCTSwiftUI: 88767b796e06cd4af8dca2f7a3f97fccf1d723e0
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { PullToRefreshBox, Host, LazyColumn, ListItem } from '@expo/ui/jetpack-compose';
import { PullToRefreshBox, Host, LazyColumn, ListItem, Text } from '@expo/ui/jetpack-compose';
import { fillMaxSize } from '@expo/ui/jetpack-compose/modifiers';
import * as React from 'react';

Expand All @@ -17,26 +17,36 @@ export default function PullToRefreshBoxScreen() {
const basic = useSimulatedRefresh();

return (
<Host matchContents>
<Host matchContents={{ horizontal: true }} style={{ height: '100%' }}>
<PullToRefreshBox
isRefreshing={basic.refreshing}
onRefresh={basic.onRefresh}
contentAlignment="topCenter">
<LazyColumn modifiers={[fillMaxSize()]}>
<ListItem>
<ListItem.HeadlineContent>Item 1</ListItem.HeadlineContent>
<ListItem.HeadlineContent>
<Text>Item 1</Text>
</ListItem.HeadlineContent>
</ListItem>
<ListItem>
<ListItem.HeadlineContent>Item 2</ListItem.HeadlineContent>
<ListItem.HeadlineContent>
<Text>Item 2</Text>
</ListItem.HeadlineContent>
</ListItem>
<ListItem>
<ListItem.HeadlineContent>Item 3</ListItem.HeadlineContent>
<ListItem.HeadlineContent>
<Text>Item 3</Text>
</ListItem.HeadlineContent>
</ListItem>
<ListItem>
<ListItem.HeadlineContent>Item 4</ListItem.HeadlineContent>
<ListItem.HeadlineContent>
<Text>Item 4</Text>
</ListItem.HeadlineContent>
</ListItem>
<ListItem>
<ListItem.HeadlineContent>Item 5</ListItem.HeadlineContent>
<ListItem.HeadlineContent>
<Text>Item 5</Text>
</ListItem.HeadlineContent>
</ListItem>
</LazyColumn>
</PullToRefreshBox>
Expand Down
2 changes: 1 addition & 1 deletion docs/components/DocumentationPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ export default function DocumentationPage({
<blockquote className="sr-only">
<p>
For the complete documentation index, see <A href="/llms.txt">llms.txt</A>. Use this
Use this file to discover all available pages.
file to discover all available pages.
</p>
</blockquote>
{children}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import { APIInstallSection } from '~/components/plugins/InstallSection';

Expo UI provides three carousel components matching the official Jetpack Compose [Carousel](https://developer.android.com/develop/ui/compose/components/carousel) API: `HorizontalCenteredHeroCarousel`, `HorizontalMultiBrowseCarousel`, and `HorizontalUncontainedCarousel`.

> **Note:** Carousel is a horizontally scrollable component, so the parent `Host` must provide a finite width on the scroll axis. Use `matchContents={{ vertical: true }}` together with `style={{ width: '100%' }}` (or any finite width). See [Match contents in Host reference](host/#match-contents) for details.

## Installation

<APIInstallSection />
Expand All @@ -29,7 +31,7 @@ export default function CenteredHeroExample() {
const colors = ['#6200EE', '#03DAC5', '#FF5722', '#4CAF50', '#2196F3'];

return (
<Host matchContents>
<Host matchContents={{ vertical: true }} style={{ width: '100%' }}>
<HorizontalCenteredHeroCarousel itemSpacing={8}>
{colors.map((color, index) => (
<Box
Expand Down Expand Up @@ -57,7 +59,7 @@ export default function MultiBrowseExample() {
const colors = ['#6200EE', '#03DAC5', '#FF5722', '#4CAF50', '#2196F3'];

return (
<Host matchContents>
<Host matchContents={{ vertical: true }} style={{ width: '100%' }}>
<HorizontalMultiBrowseCarousel
preferredItemWidth={200}
itemSpacing={8}
Expand Down Expand Up @@ -88,7 +90,7 @@ export default function UncontainedExample() {
const items = ['Photo 1', 'Photo 2', 'Photo 3', 'Photo 4', 'Photo 5'];

return (
<Host matchContents>
<Host matchContents={{ vertical: true }} style={{ width: '100%' }}>
<HorizontalUncontainedCarousel
itemWidth={160}
itemSpacing={12}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import { APIInstallSection } from '~/components/plugins/InstallSection';

Expo UI DateTimePicker matches the official Jetpack Compose [Date Picker](https://developer.android.com/develop/ui/compose/components/datepickers) and [Time Picker](https://developer.android.com/develop/ui/compose/components/time-pickers) APIs and supports date, time, and combined selection.

> **Note:** The date variants render Material's calendar grid and input field, both of which scroll horizontally internally. The parent `Host` must provide a finite width on the horizontal axis, use `matchContents={{ vertical: true }}` together with `style={{ width: '100%' }}` (or any finite width). See [Match contents in Host reference](host/#match-contents) for details.

## Installation

<APIInstallSection />
Expand All @@ -27,7 +29,7 @@ export default function DatePickerExample() {
const [selectedDate, setSelectedDate] = useState(new Date());

return (
<Host matchContents>
<Host matchContents={{ vertical: true }} style={{ width: '100%' }}>
<DateTimePicker
onDateSelected={date => {
setSelectedDate(date);
Expand All @@ -51,7 +53,7 @@ export default function TimePickerExample() {
const [selectedDate, setSelectedDate] = useState(new Date());

return (
<Host matchContents>
<Host matchContents={{ vertical: true }} style={{ width: '100%' }}>
<DateTimePicker
onDateSelected={date => {
setSelectedDate(date);
Expand All @@ -77,7 +79,7 @@ export default function InputVariantExample() {
const [selectedDate, setSelectedDate] = useState(new Date());

return (
<Host matchContents>
<Host matchContents={{ vertical: true }} style={{ width: '100%' }}>
<DateTimePicker
onDateSelected={date => {
setSelectedDate(date);
Expand Down
38 changes: 38 additions & 0 deletions docs/pages/versions/unversioned/sdk/ui/jetpack-compose/host.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,44 @@ export default function MatchContents() {
}
```

> **Note:** Do not use `matchContents` on the same axis as a scrollable child (`LazyRow`, `LazyColumn`, `Carousel`, or anything using `Modifier.horizontalScroll`/`verticalScroll`). Scrollables require a finite max constraint on their scroll axis and `matchContents` propagates an unbounded one.

The following example crashes:

```tsx MatchContentsCrash.tsx
import { Host, LazyRow, Text } from '@expo/ui/jetpack-compose';

export default function MatchContentsCrash() {
return (
<Host matchContents>
<LazyRow>
{Array.from({ length: 5 }).map((_, i) => (
<Text key={i}>Item {i}</Text>
))}
</LazyRow>
</Host>
);
}
```

Either drop `matchContents` on the scroll axis or give the `Host` a finite size on that axis via `style`:

```tsx MatchContentsFix.tsx
import { Host, LazyRow, Text } from '@expo/ui/jetpack-compose';

export default function MatchContentsFix() {
return (
<Host matchContents={{ vertical: true }} style={{ width: '100%' }}>
<LazyRow>
{Array.from({ length: 5 }).map((_, i) => (
<Text key={i}>Item {i}</Text>
))}
</LazyRow>
</Host>
);
}
```

### With style

Apply standard React Native styles to the `Host` wrapper.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,26 @@ export default function BasicLazyColumn() {
Use the `verticalArrangement` prop to control how items are spaced within the list. Pass a string value like `'spaceBetween'` or an object like `{ spacedBy: 8 }` for fixed spacing in dp.

```tsx LazyColumnArrangement.tsx
import { Host, LazyColumn, ListItem } from '@expo/ui/jetpack-compose';
import { Host, LazyColumn, ListItem, Text } from '@expo/ui/jetpack-compose';

export default function LazyColumnArrangement() {
return (
<Host style={{ height: 400 }}>
<LazyColumn verticalArrangement={{ spacedBy: 8 }} horizontalAlignment="center">
<ListItem>
<ListItem.HeadlineContent>Spaced item 1</ListItem.HeadlineContent>
<ListItem.HeadlineContent>
<Text>Spaced Item 1</Text>
</ListItem.HeadlineContent>
</ListItem>
<ListItem>
<ListItem.HeadlineContent>Spaced item 2</ListItem.HeadlineContent>
<ListItem.HeadlineContent>
<Text>Spaced Item 2</Text>
</ListItem.HeadlineContent>
</ListItem>
<ListItem>
<ListItem.HeadlineContent>Spaced item 3</ListItem.HeadlineContent>
<ListItem.HeadlineContent>
<Text>Spaced Item 3</Text>
</ListItem.HeadlineContent>
</ListItem>
</LazyColumn>
</Host>
Expand Down
20 changes: 20 additions & 0 deletions docs/pages/versions/unversioned/sdk/ui/swift-ui/host.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,26 @@ export default function MatchContentsExample() {
}
```

> **Note:** Do not use `matchContents` on the same axis as a scroll container (`ScrollView`, `List`, `Form`, `LazyHStack`, `LazyVStack`). `matchContents` resolves to SwiftUI's `.fixedSize`, which sizes the scroll container to its content. It also leaves nothing past the viewport to scroll into, so scrolling silently stops working. Use `matchContents={{ vertical: true }}` together with `style={{ width: '100%' }}` (or any finite width on the scroll axis).

```tsx ScrollViewMatchContents.tsx
import { Host, HStack, ScrollView, Text } from '@expo/ui/swift-ui';

export default function ScrollViewMatchContents() {
return (
<Host matchContents={{ vertical: true }} style={{ width: '100%' }}>
<ScrollView axes="horizontal">
<HStack spacing={12}>
{Array.from({ length: 20 }).map((_, i) => (
<Text key={i}>Item {i}</Text>
))}
</HStack>
</ScrollView>
</Host>
);
}
```

### Explicit sizing with style

Use `style` to set explicit sizes on the `Host`, such as filling the available space with `flex: 1`.
Expand Down
Loading
Loading