Skyroc Native UI

NavBar

页面顶部导航栏,左中右三区布局

导航栏(NavBar)是页面顶部的标题栏:左侧返回、中间标题、右侧操作。组件不感知任何路由方案 —— 返回行为由使用方通过 onLeftPress 注入,它只负责布局与样式。

import { NavBar } from '@skyroc/native-ui';

基础用法

只给 title 即可。导航栏主体高度按平台惯例取值:iOS 44、Android 56,外层容器默认再加上顶部安全区内边距。

NavBarBasic.tsx
Loading…
import { NavBar } from '@skyroc/native-ui';
import { View } from 'react-native';

const NavBarBasic = () => {
  return (
    <View className="bg-background">
      <NavBar
        safeAreaTop={false}
        title="页面标题"
      />
    </View>
  );
};

export { NavBarBasic };

标题是绝对定位居中的(左右各留出 64 的按钮区),所以长标题不会把两侧内容挤走,而是单行截断。

何时使用

  • 页面级的顶部标题栏。
  • 页内的分段切换请用 Tabs;悬浮在内容之上的操作条请自行用 View 拼。

返回与操作

leftArrow 显示返回箭头,rightText + onRightPress 提供右侧主操作。

NavBarAction.tsx
Loading…
import { NavBar } from '@skyroc/native-ui';
import { Alert, View } from 'react-native';

const NavBarAction = () => {
  function handleBack() {
    Alert.alert('点击了返回');
  }

  function handleAction() {
    Alert.alert('点击了操作');
  }

  return (
    <View className="bg-background">
      <NavBar
        leftArrow
        safeAreaTop={false}
        rightText="完成"
        title="编辑资料"
        onLeftPress={handleBack}
        onRightPress={handleAction}
      />
    </View>
  );
};

export { NavBarAction };

箭头是否可点由 onLeftPress 决定:只开 leftArrow 而不给回调会渲染成不可点状态。两侧按钮都带 hitSlop={5}。

文字导航

leftText 与 rightText 可以同时使用,两侧都是文字按钮(左侧文字可与箭头并存)。

NavBarText.tsx
Loading…
import { NavBar } from '@skyroc/native-ui';
import { Alert, View } from 'react-native';

const NavBarText = () => {
  function handleBack() {
    Alert.alert('点击了取消');
  }

  function handleAction() {
    Alert.alert('点击了保存');
  }

  return (
    <View className="bg-background">
      <NavBar
        leftText="取消"
        safeAreaTop={false}
        rightText="保存"
        title="新建内容"
        onLeftPress={handleBack}
        onRightPress={handleAction}
      />
    </View>
  );
};

export { NavBarText };

禁用状态

leftDisabled / rightDisabled 阻止对应区域点击并降到 50% 不透明度。

NavBarDisabled.tsx
Loading…
import { NavBar } from '@skyroc/native-ui';
import { Alert, View } from 'react-native';

const NavBarDisabled = () => {
  function handlePress() {
    Alert.alert('禁用状态下不应触发');
  }

  return (
    <View className="gap-3">
      <View className="overflow-hidden rounded-xl border border-border bg-background">
        <NavBar
          leftArrow
          leftDisabled
          rightDisabled
          rightText="提交"
          safeAreaTop={false}
          title="两侧均禁用"
          onLeftPress={handlePress}
          onRightPress={handlePress}
        />
      </View>
    </View>
  );
};

export { NavBarDisabled };

自定义内容

left / right / title 都接受任意节点:left 会覆盖 leftArrow 与 leftText,right 会覆盖 rightText。onTitlePress 让标题区域可点。

NavBarCustomContent.tsx
Loading…
import Octicons from '@expo/vector-icons/Octicons';
import { NavBar, Text } from '@skyroc/native-ui';
import { Alert, View } from 'react-native';

const NavBarCustomContent = () => {
  function handleTitlePress() {
    Alert.alert('点击了自定义标题');
  }

  return (
    <View className="overflow-hidden rounded-xl border border-border bg-background">
      <NavBar
        safeAreaTop={false}
        left={
          <View className="rounded-full bg-secondary px-2 py-1">
            <Text className="text-xs text-foreground">关闭</Text>
          </View>
        }
        right={<Text className="text-sm font-medium text-success">发布</Text>}
        title={
          <View className="flex-row items-center gap-1">
            <Text className="font-semibold">自定义标题</Text>
            <Octicons
              color="var(--muted-foreground)"
              name="chevron-down"
              size={14}
            />
          </View>
        }
        onTitlePress={handleTitlePress}
      />
    </View>
  );
};

export { NavBarCustomContent };

标题铺满整行,不可点时组件会给它 pointerEvents="none" 让出触摸 —— 否则它会盖掉两侧按钮。

颜色与样式覆盖

backColor 单独指定返回箭头颜色(缺省时箭头包在 Text 里,继承主题前景色、跟随明暗模式)。className 落在导航栏主体上,classNames 按 slot 细粒度覆盖:

slot作用位置
container最外层容器,承载顶部安全区内边距
root导航栏主体(高度、横向内边距、下边框)
left左侧按钮区
title标题区(绝对定位居中)
right右侧按钮区
NavBarStyles.tsx
Loading…
import { NavBar } from '@skyroc/native-ui';
import { View } from 'react-native';

const NavBarStyles = () => {
  return (
    <View className="overflow-hidden rounded-xl border border-primary-200 bg-primary-50">
      <NavBar
        leftArrow
        backColor="var(--destructive)"
        className="bg-primary-50 px-5"
        classNames={{
          container: 'bg-primary-50',
          left: 'rounded-full bg-background px-2 py-1',
          right: 'rounded-full bg-primary-100 px-3 py-1',
          title: 'inset-x-20',
          root: 'border-primary-200'
        }}
        rightText="操作"
        safeAreaTop={false}
        title="样式槽覆盖"
      />
    </View>
  );
};

export { NavBarStyles };

注意 className 与 classNames.root 都作用在主体上,此处 classNames.root 排在更后面、优先级更高(与库内多数组件相反)。

无分隔线

border={false} 去掉底部分隔线,常用于导航栏与下方内容同色的场景。

NavBarBorderless.tsx
Loading…
import { NavBar } from '@skyroc/native-ui';
import { Alert, View } from 'react-native';

const NavBarBorderless = () => {
  function handleBack() {
    Alert.alert('点击了返回');
  }

  return (
    <View className="bg-background">
      <NavBar
        border={false}
        leftArrow
        safeAreaTop={false}
        title="沉浸式页面"
        onLeftPress={handleBack}
      />
    </View>
  );
};

export { NavBarBorderless };

safeAreaTop(默认 true)控制顶部安全区内边距 —— 上面这些内嵌 demo 都关掉了它,实际页面里保持默认即可。安全区尺寸由应用根节点的 Uniwind.updateInsets 同步,不依赖 SafeAreaProvider。

API

属性说明类型默认值
title标题,字符串会单行截断;也接受任意节点ReactNode-
onTitlePress标题点击回调;未提供时标题不拦截触摸() => void-
leftArrow是否显示左侧返回箭头booleanfalse
leftText左侧文字string-
left自定义左侧内容,会覆盖 leftArrow 与 leftTextReactNode-
onLeftPress左侧点击回调;未提供时左侧不可点() => void-
leftDisabled禁用左侧按钮booleanfalse
rightText右侧文字string-
right自定义右侧内容,会覆盖 rightTextReactNode-
onRightPress右侧点击回调;未提供时右侧不可点() => void-
rightDisabled禁用右侧按钮booleanfalse
backColor返回箭头颜色,缺省时继承主题前景色string-
border是否显示下边框booleantrue
safeAreaTop是否使用顶部安全区内边距booleantrue
className导航栏主体类名string-
classNames各 slot 的类名覆盖,见「颜色与样式覆盖」一节SlotClassNames<NavBarSlots>-
ref最外层容器的 ref,可用于 measure 导航栏实际高度(含安全区)Ref<View>-

类型

import type { NavBarProps, NavBarSlots } from '@skyroc/native-ui';

NavBarSlots

可通过 classNames 覆盖的 slot 名称。

'container' | 'left' | 'right' | 'root' | 'title'

SlotClassNames

classNames 的取值形态:把 slot 名映射到类名,每个 slot 都可选。本页用到的 slot 见 NavBarSlots。

Partial<Record<Slots, string>>

包内还导出了 navBarVariants。