Layout and lists

Island

Where native views meet React Native layout.

iOSSwiftUI HostAndroidCompose HostBrings its own host — renders anywhere
Island on iOS
iOSSwiftUI Host
Island on Android
AndroidCompose Host

Import

ts
import {Island, RnView} from '@hzblj/kara-ui'

Props

A host for native atoms in a React Native layout — the SwiftUI / Compose Host an @expo/ui tree mounts into.

PropTypeDefaultDescription
childrenReactNode—

The native views it hosts.

matchContentsbooleantrue

Sizes the island's height to its native content while the width still comes from the parent, which is what a full-width card wants. On by default. Only the height is ever measured: auto-sizing the width maps to fixedSize(horizontal: true), so the native side ignores the proposed width and resolves a wide stack's ideal width as unbounded.

Turn it off — and give the island an explicit size via style — when the subtree contains an RnView: that host drives its SwiftUI frame from the child's Yoga-laid-out bounds while this one writes its measured size back into the Yoga style, and the two together spin a layout loop that hangs the main thread as soon as the views lay out on screen.

styleStyleProp<ViewStyle>—

A React Native style for the host view — its size and placement. It needs a height when matchContents is off.

testIDstring—

Test identifier, forwarded to the host view on iOS — Android ignores it.

children
ReactNode

The native views it hosts.

matchContentstrue
boolean

Sizes the island's height to its native content while the width still comes from the parent, which is what a full-width card wants. On by default. Only the height is ever measured: auto-sizing the width maps to fixedSize(horizontal: true), so the native side ignores the proposed width and resolves a wide stack's ideal width as unbounded.

Turn it off — and give the island an explicit size via style — when the subtree contains an RnView: that host drives its SwiftUI frame from the child's Yoga-laid-out bounds while this one writes its measured size back into the Yoga style, and the two together spin a layout loop that hangs the main thread as soon as the views lay out on screen.

style
StyleProp<ViewStyle>

A React Native style for the host view — its size and placement. It needs a height when matchContents is off.

testID
string

Test identifier, forwarded to the host view on iOS — Android ignores it.

RnView

Carries a React Native view into a SwiftUI or Compose tree — @expo/ui's RNHostView on both platforms.

PropTypeDefaultDescription
children*ReactElement—

A single React Native view. It may not contain React Native text: a bare string becomes a RawText node, which has no component view, so mounting it across the SwiftUI host boundary fails the RCTComponentViewFactory assertion and takes the whole app down. @expo/ui states the rule itself in ListItem.ios.tsx — "SwiftUI hosts can't render bare strings" — and wraps every raw string in a SwiftUI Text before it reaches a host. Do the same: use the Text atom inside the host, and keep RnText outside it.

matchContentsbooleantrue

Sizes the host to the child's measured layout. On by default because a raw RN view has no intrinsic size and would otherwise stretch to fill the SwiftUI parent.

testIDstring—

Not forwarded on either platform — give the child its own testID.

children*
ReactElement

A single React Native view. It may not contain React Native text: a bare string becomes a RawText node, which has no component view, so mounting it across the SwiftUI host boundary fails the RCTComponentViewFactory assertion and takes the whole app down. @expo/ui states the rule itself in ListItem.ios.tsx — "SwiftUI hosts can't render bare strings" — and wraps every raw string in a SwiftUI Text before it reaches a host. Do the same: use the Text atom inside the host, and keep RnText outside it.

matchContentstrue
boolean

Sizes the host to the child's measured layout. On by default because a raw RN view has no intrinsic size and would otherwise stretch to fill the SwiftUI parent.

testID
string

Not forwarded on either platform — give the child its own testID.

Platform notes

  • Native views only render inside an Island or a Screen. Outside one they silently disappear (in development, a warning says so).
  • Sized to its content by default. Give it matchContents={false} and a height when the content has none of its own — a List, a Form, a Pager — or contains an RnView.
  • RnView carries a React Native view back into a native layout.