NebulaNebula

@nebula-rn/components

Nebula cross-platform UI component library API reference, including complete Props, event callbacks, and platform differences for each component.

@nebula-rn/components provides a set of cross-platform React Native components for miniapp developers. It also re-exports basic React Native components.

Peer Dependencies: react >= 18, react-native >= 0.83


Camera

Camera component supporting photo capture and QR code scanning modes. Based on react-native-vision-camera.

PlatformSupport
iOS✅
Android✅
import { Camera } from '@nebula-rn/components';

Example:

import { useState } from 'react';
import { Alert, View } from 'react-native';
import { Camera } from '@nebula-rn/components';

export default function ScanCodeDemo() {
  const [mode, setMode] = useState<'normal' | 'scanCode'>('scanCode');

  return (
    <View style={{ height: 240, borderRadius: 12, overflow: 'hidden' }}>
      <Camera
        mode={mode}
        devicePosition="back"
        flash="auto"
        onScanCode={event => {
          Alert.alert('Scan Result', event.result);
          setMode('normal');
        }}
        onError={error => {
          Alert.alert('Camera Error', error.message);
        }}
      />
    </View>
  );
}

Props:

ParameterTypeRequiredDefaultDescription
idstringNo—Component ID.
classNamestringNo—CSS class name.
styleStyleProp<ViewStyle>No—Custom styles.
mode'normal' | 'scanCode'No'normal'Camera mode. 'scanCode' enables QR/barcode scanning.
resolution'low' | 'medium' | 'high'No—Camera resolution.
devicePosition'front' | 'back'No'back'Front or back camera.
flash'auto' | 'on' | 'off' | 'torch'No—Flash mode.

Event Callbacks:

CallbackTypeDescription
onInitDone(event: CameraInitEventDetail) => voidCamera initialization complete.
onReady(event: CameraInitEventDetail) => voidCamera ready.
onScanCode(event: CameraScanCodeEventDetail) => voidQR code scanned (only in mode='scanCode').
onError(error: CameraError) => voidError occurred.

CameraInitEventDetail:

FieldTypeDescription
maxZoomnumberMaximum zoom supported by the device.

CameraScanCodeEventDetail:

FieldTypeDescription
resultstringScanned result text.
fullResultstringFull scan result.
rawDatastringRaw data.
charSetstringCharacter encoding.
typeCodeType | 'unknown'Code type (e.g., QR, EAN-13).

CameraError:

FieldTypeDescription
messagestringError message.
codestring | undefinedError code, e.g., 'PERMISSION_DENIED', 'PERMISSION_ERROR'.
nativeErrorunknownNative error object.

Permission Required: Camera permission (automatically requested when component mounts).

Default Size: 300x300, overflow: hidden, black background.

Supported Code Types: QR Code, EAN-13 barcode.

Native Dependency: react-native-vision-camera v4.7.3


Map

Map display and interaction component. Based on react-native-maps.

Warning for Android

If you intend to use the Map component on the Android platform, please refer to the react-native-maps documentation beforehand to learn how to configure an API Key for Android. Otherwise, your app may crash.

https://github.com/react-native-maps/react-native-maps/blob/master/docs/installation.md#android

PlatformSupport
iOS✅
Android✅
import { Map } from '@nebula-rn/components';

Example:

import { Map } from '@nebula-rn/components';

const markers = [
  {
    id: 1,
    latitude: 31.2304,
    longitude: 121.4737,
    title: 'Shanghai Office',
    iconPath: 'https://example.com/marker.png',
    callout: {
      content: 'Click for details',
      display: 'BYCLICK',
      bgColor: '#ffffff',
      padding: 8,
    },
  },
];

export default function OfficeMap() {
  return (
    <Map
      latitude={31.2304}
      longitude={121.4737}
      scale={14}
      markers={markers}
      showCompass
      enableZoom
      enableScroll
      style={{ height: 280, borderRadius: 12 }}
    />
  );
}

Props:

ParameterTypeRequiredDefaultDescription
latitudenumberYes—Center latitude.
longitudenumberYes—Center longitude.
scalenumberNo—Zoom level.
markersMarkerItem[]No—List of markers.
polylinePolylineItem[]No—List of polylines.
polygonsPolygonItem[]No—List of polygons.
circlesCircleItem[]No—List of circle overlays.
includePointsCoordinate[]No—Coordinates to include within viewport.
showLocationbooleanNofalseWhether to show user's current location.
subkeystringNo—Map service subkey.
enable3DbooleanNo—Enable 3D map.
showCompassbooleanNotrueShow compass.
enableOverlookingbooleanNo—Allow overlooking (pitch/tilt).
enableZoombooleanNotrueAllow zooming.
enableScrollbooleanNotrueAllow scrolling.
enableRotatebooleanNotrueAllow rotation.

Event Callbacks:

CallbackTypeDescription
onMarkerClick(markerId: number) => voidMarker clicked.
onCalloutClick(markerId: number) => voidMarker callout clicked.
onControlClick(controlId?: number) => voidControl clicked.
onRegionChange(event: RegionChangeEvent) => voidMap region changed.
onClick(coordinate: Coordinate) => voidEmpty area of map clicked.
onUpdated() => voidMap update complete.
onPoiClick(event: any) => voidPoint of interest clicked.

MarkerItem:

FieldTypeRequiredDescription
idnumberYesUnique ID.
latitudenumberYesLatitude.
longitudenumberYesLongitude.
titlestringNoTitle text.
iconPathstringYesIcon URI.
rotatenumberNoRotation angle.
alphanumberNoOpacity.
calloutCalloutItemNoCallout configuration.
anchor{ x: number; y: number }NoIcon anchor point.

CalloutItem:

FieldTypeRequiredDescription
contentstringNoCallout content text.
colorstringNoText color.
fontSizenumberNoFont size.
borderRadiusnumberNoBorder radius.
borderWidthnumberNoBorder width.
borderColorstringNoBorder color.
bgColorstringNoBackground color.
paddingnumberNoPadding.
display'BYCLICK' | 'ALWAYS'NoDisplay mode. 'BYCLICK' shows on click, 'ALWAYS' always visible.
textAlign'left' | 'right' | 'center'NoText alignment.

PolylineItem:

FieldTypeRequiredDescription
pointsCoordinate[]YesPolyline coordinate points.
colorstringNoLine color.
widthnumberNoLine width.

PolygonItem:

FieldTypeRequiredDescription
pointsCoordinate[]YesPolygon coordinate points.
strokeWidthnumberNoBorder width.
strokeColorstringNoBorder color.
fillColorstringNoFill color.

CircleItem:

FieldTypeRequiredDescription
latitudenumberYesCenter latitude.
longitudenumberYesCenter longitude.
radiusnumberYesRadius in meters.
colorstringNoBorder color.
fillColorstringNoFill color.
strokeWidthnumberNoBorder width.

RegionChangeEvent:

FieldTypeDescription
type'begin' | 'end'Change stage.
timeStampnumberTimestamp.
causedBy'scale' | 'drag' | 'update'Trigger cause.

Zoom Constraints: Minimum 5, maximum 18.

Default Viewport: LATITUDE_DELTA = 0.0922.

Native Dependency: react-native-maps


Progress

Progress bar component with animation support.

PlatformSupport
iOS✅
Android✅
import { Progress } from '@nebula-rn/components';

Example:

import { View } from 'react-native';
import { Progress } from '@nebula-rn/components';

export default function UploadProgress() {
  return (
    <View style={{ gap: 12 }}>
      <Progress percent={32} showInfo />
      <Progress
        percent={76}
        active
        activeMode="forwards"
        strokeWidth={8}
        borderRadius={999}
        activeColor="#2563eb"
        backgroundColor="#dbeafe"
      />
    </View>
  );
}

Props:

ParameterTypeRequiredDefaultDescription
percentnumberYes—Progress percentage (0-100).
showInfobooleanNofalseWhether to show percentage text on the right.
strokeWidthnumber | stringNo6Progress bar height (px).
activeColorstringNo'#09BB07'Color of the completed portion.
backgroundColorstringNo'#EBEBEB'Background color of the incomplete portion.
borderRadiusnumber | stringNo0Border radius.
fontSizenumber | stringNo—Percentage text font size.
activebooleanNo—Whether to enable animation.
activeMode'backwards' | 'forwards'No'backwards'Animation mode.
styleStyleProp<ViewStyle>No—Custom styles.

Event Callbacks:

CallbackTypeDescription
onActiveEnd(event: { percent: number }) => voidProgress animation ended.

Animation Modes:

ModeBehavior
backwardsResets to zero first, then animates to target value.
forwardsAnimates from current value to target value.

Animation Duration: (percent / 100) * 1000 ms, linear easing.


RichText

Rich text rendering component that uses WebView to render HTML content with automatic height adjustment.

PlatformSupport
iOS✅
Android✅
import { RichText } from '@nebula-rn/components';

Example:

import { RichText } from '@nebula-rn/components';

const article = `
  <h1 style="font-size: 20px; color: #0f172a;">Welcome to Nebula</h1>
  <p style="color: #475569; line-height: 1.7;">
    RichText is suitable for rendering operational articles, activity rules, service agreements, and other HTML content.
  </p>
  <ul>
    <li>Supports basic tags</li>
    <li>Supports inline styles</li>
    <li>Automatically adjusts height</li>
  </ul>
`;

export default function RichArticle() {
  return <RichText html={article} style={{ backgroundColor: '#fff' }} />;
}

Props:

ParameterTypeRequiredDefaultDescription
htmlstringYes—HTML content to render.
styleStyleProp<ViewStyle>No—Custom styles.

Features:

  • Automatically calculates and adjusts content height (via injected JS to get scrollHeight).
  • Internal scrolling disabled.
  • Transparent background.
  • Default font: -apple-system, system-ui.
  • Viewport configuration: width=device-width, initial-scale=1, user-scalable=0.

Native Dependency: react-native-webview


Slider

Slider selector component, supporting both controlled and uncontrolled modes.

PlatformSupport
iOS✅
Android✅
import { Slider } from '@nebula-rn/components';

Example:

import { useState } from 'react';
import { Text, View } from 'react-native';
import { Slider } from '@nebula-rn/components';

export default function VolumeSlider() {
  const [value, setValue] = useState(40);

  return (
    <View style={{ gap: 8 }}>
      <Text>Volume: {value}</Text>
      <Slider
        min={0}
        max={100}
        step={5}
        value={value}
        showValue
        activeColor="#2563eb"
        onChanging={event => setValue(event.value)}
        onChange={event => setValue(event.value)}
      />
    </View>
  );
}

Props:

ParameterTypeRequiredDefaultDescription
minnumberNo0Minimum value.
maxnumberNo100Maximum value.
stepnumberNo1Step increment.
valuenumberNo—Controlled value. Passing this enters controlled mode.
defaultValuenumberNo—Uncontrolled initial value.
disabledbooleanNo—Disable interaction.
activeColorstringNo'#1aad19'Color of the selected track area.
backgroundColorstringNo'#e9e9e9'Color of the unselected track area.
blockColorstringNo'#fff'Thumb color.
showValuebooleanNofalseWhether to show current value on the right.
namestringNo—Form field name.
styleStyleProp<ViewStyle>No—Custom styles.

Event Callbacks:

CallbackTypeDescription
onChange(event: { value: number }) => voidTriggered when dragging ends.
onChanging(event: { value: number }) => voidTriggered continuously during dragging.

Controlled Mode Sync Interval: 50ms debounce.

Native Dependency: @react-native-community/slider


Swiper

Image/content carousel component supporting autoplay, looping, and pagination indicators.

PlatformSupport
iOS✅
Android✅
import { Swiper } from '@nebula-rn/components';

Example:

import { Image, View } from 'react-native';
import { Swiper } from '@nebula-rn/components';

const banners = [
  'https://images.unsplash.com/photo-1500530855697-b586d89ba3ee?w=1200',
  'https://images.unsplash.com/photo-1493246507139-91e8fad9978e?w=1200',
  'https://images.unsplash.com/photo-1507525428034-b723cf961d3e?w=1200',
];

export default function BannerSwiper() {
  return (
    <View style={{ height: 180, borderRadius: 12, overflow: 'hidden' }}>
      <Swiper autoplay circular indicatorDots interval={3000}>
        {banners.map(uri => (
          <Image
            key={uri}
            source={{ uri }}
            style={{ width: '100%', height: '100%' }}
            resizeMode="cover"
          />
        ))}
      </Swiper>
    </View>
  );
}

Props:

ParameterTypeRequiredDefaultDescription
indicatorDotsbooleanNo—Whether to show pagination indicators.
indicatorColorstringNo'rgba(0,0,0,0.3)'Inactive indicator color.
indicatorActiveColorstringNo'#000'Active indicator color.
autoplaybooleanNo—Whether to autoplay.
currentnumberNo0Currently displayed slide index.
intervalnumberNo5000Autoplay interval (ms).
circularbooleanNo—Whether to loop (infinite scrolling).
verticalbooleanNo—Whether to scroll vertically.
styleStyleProp<ViewStyle>No—Custom styles.

Event Callbacks:

CallbackTypeDescription
onChange(event: { current: number }) => voidTriggered when slide changes.
onAnimationFinish(event: { current: number }) => voidTriggered after slide animation completes.

Child Components:

<Swiper autoplay circular indicatorDots>
  <Swiper.Item>
    <Image source={img1} />
  </Swiper.Item>
  <Swiper.Item>
    <Image source={img2} />
  </Swiper.Item>
</Swiper>

Indicator Style: Dots 8x8, borderRadius 8, inactive #999, active #333.

Native Dependencies: react-native-reanimated-carousel v4.0.3, react-native-reanimated v4.2.3


Video

Video player component supporting fullscreen, poster image, and playback controls.

PlatformSupport
iOS✅
Android✅
import { Video } from '@nebula-rn/components';

Example:

import { Video } from '@nebula-rn/components';

export default function CourseVideo() {
  return (
    <Video
      src="https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
      poster="https://peach.blender.org/wp-content/uploads/title_anouncement.jpg?x11217"
      controls
      objectFit="cover"
      style={{ height: 220, borderRadius: 12, backgroundColor: '#000' }}
      onError={event => {
        console.error('video error', event.errMsg);
      }}
    />
  );
}

Props:

ParameterTypeRequiredDefaultDescription
srcstringYes—Video resource URI.
durationnumberNo—Video duration (ms).
controlsbooleanNotrueWhether to show playback controls.
autoplaybooleanNofalseWhether to autoplay.
loopbooleanNofalseWhether to loop.
mutedbooleanNofalseWhether to mute.
initialTimenumberNo0Initial playback position (ms).
objectFit'contain' | 'fill' | 'cover'No'contain'Video scaling mode.
posterstringNo—Poster image URI, shown before playback.
showCenterPlayBtnbooleanNotrueWhether to show center play button.
styleStyleProp<ViewStyle>No—Custom styles.
childrenReactNodeNo—Content to overlay on the video.

Event Callbacks:

CallbackTypeDescription
onLoad() => voidVideo loaded.
onPlay() => voidPlayback started.
onPause() => voidPlayback paused.
onEnded() => voidPlayback ended.
onError(event: { errMsg: string }) => voidPlayback error.
onTimeUpdate(event: VideoTimeUpdateEvent) => voidPlayback progress updated.
onFullscreenChange(event: VideoFullscreenChangeEvent) => voidFullscreen state changed.
onLoadedMetaData(event: VideoMetaDataEvent) => voidVideo metadata loaded.

VideoTimeUpdateEvent:

FieldTypeDescription
currentTimenumberCurrent playback position (ms).
durationnumberTotal video duration (ms).

VideoFullscreenChangeEvent:

FieldTypeDescription
fullScreenbooleanWhether fullscreen is active.
direction'vertical' | 'horizontal'Fullscreen direction.

VideoMetaDataEvent:

FieldTypeDescription
widthnumberVideo width (px).
heightnumberVideo height (px).
durationnumberVideo duration (ms).

ObjectFit Mapping:

objectFitReact Native ResizeMode
'contain'ResizeMode.CONTAIN
'fill'ResizeMode.STRETCH
'cover'ResizeMode.COVER

Default Size: Width 100%, height 225px, black background.

Progress Update Frequency: 250ms.

Native Dependency: react-native-video v6.19.1


WebView

Embedded web content component, extending all functionality of react-native-webview.

PlatformSupport
iOS✅
Android✅
import { WebView } from '@nebula-rn/components';

Example:

import { Alert } from 'react-native';
import { WebView } from '@nebula-rn/components';

const html = `
  <html>
    <body style="font-family: -apple-system; padding: 24px;">
      <h2>Local HTML Content</h2>
      <button onclick="window.ReactNativeWebView.postMessage('clicked')">
        Send message to miniapp
      </button>
    </body>
  </html>
`;

export default function EmbeddedPage() {
  return (
    <WebView
      html={html}
      style={{ height: 320, borderRadius: 12, overflow: 'hidden' }}
      onMessage={event => {
        Alert.alert('Message received', event.nativeEvent.data);
      }}
    />
  );
}

Props:

ParameterTypeRequiredDescription
srcstringNoURL to load.
htmlstringNoHTML content to render. Takes precedence over src when provided.
styleStyleProp<ViewStyle>NoCustom styles.
...restRNWebViewPropsNoAll native react-native-webview props can be used.

Default Configuration:

  • originWhitelist: ['*'] (all sources allowed).

Native Dependency: react-native-webview


Basic Components

Miniapps can directly use React Native basic components, imported from react-native:

import { View, Text, ScrollView, Image, Button } from 'react-native';

Example:

import { Button, Image, ScrollView, Text, View } from 'react-native';

export default function BasicLayout() {
  return (
    <ScrollView contentContainerStyle={{ padding: 16, gap: 12 }}>
      <Image
        source={{
          uri: 'https://images.unsplash.com/photo-1518837695005-2083093ee35b?w=1200',
        }}
        style={{ width: '100%', height: 180, borderRadius: 12 }}
      />
      <View style={{ gap: 6 }}>
        <Text style={{ fontSize: 20, fontWeight: '700' }}>
          Component Library Home
        </Text>
        <Text style={{ color: '#475569' }}>
          React Native basic components are still the core for building page
          layouts.
        </Text>
      </View>
      <Button title="Get Started" onPress={() => {}} />
    </ScrollView>
  );
}

Below are the commonly used basic components in miniapps:

ComponentDescription
ViewBasic container
TextText
ScrollViewScrollable container
ImageImage
ButtonButton
InputText input
TextareaMulti-line text input
BlockLayout block
Checkbox / CheckboxGroupMultiple selection
Radio / RadioGroupSingle selection
FormForm
IconIcon
LabelLabel
NavigatorNavigation
Picker / PickerViewPicker
SwitchSwitch
CoverImage / CoverViewOverlay views
PageContainerPage container
SwiperItemCarousel item

Native Dependencies

When using modules that contain native components, the corresponding native dependencies need to be installed in the host project:

DependencyVersionUsed For
react-native-vision-camera^4.7.3Camera
react-native-video^6.19.1Video
react-native-reanimated^4.2.3Swiper animation
react-native-reanimated-carousel^4.0.3Swiper
react-native-gesture-handler^2.30.0Gesture interaction
react-native-webview—RichText, WebView
react-native-maps—Map
@react-native-community/slider—Slider

On this page