NavBar
页面顶部导航栏,左中右三区布局
导航栏(NavBar)是页面顶部的标题栏:左侧返回、中间标题、右侧操作。组件不感知任何路由方案 —— 返回行为由使用方通过 onLeftPress 注入,它只负责布局与样式。
import { NavBar } from '@skyroc/native-ui';基础用法
只给 title 即可。导航栏主体高度按平台惯例取值:iOS 44、Android 56,外层容器默认再加上顶部安全区内边距。
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 提供右侧主操作。
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 可以同时使用,两侧都是文字按钮(左侧文字可与箭头并存)。
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% 不透明度。
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 让标题区域可点。
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 | 右侧按钮区 |
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} 去掉底部分隔线,常用于导航栏与下方内容同色的场景。
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
NavBar
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| title | 标题,字符串会单行截断;也接受任意节点 | ReactNode | - |
| onTitlePress | 标题点击回调;未提供时标题不拦截触摸 | () => void | - |
| leftArrow | 是否显示左侧返回箭头 | boolean | false |
| leftText | 左侧文字 | string | - |
| left | 自定义左侧内容,会覆盖 leftArrow 与 leftText | ReactNode | - |
| onLeftPress | 左侧点击回调;未提供时左侧不可点 | () => void | - |
| leftDisabled | 禁用左侧按钮 | boolean | false |
| rightText | 右侧文字 | string | - |
| right | 自定义右侧内容,会覆盖 rightText | ReactNode | - |
| onRightPress | 右侧点击回调;未提供时右侧不可点 | () => void | - |
| rightDisabled | 禁用右侧按钮 | boolean | false |
| backColor | 返回箭头颜色,缺省时继承主题前景色 | string | - |
| border | 是否显示下边框 | boolean | true |
| safeAreaTop | 是否使用顶部安全区内边距 | boolean | true |
| className | 导航栏主体类名 | string | - |
| classNames | 各 slot 的类名覆盖,见「颜色与样式覆盖」一节 | SlotClassNames<NavBarSlots> | - |
| ref | 最外层容器的 ref,可用于 measure 导航栏实际高度(含安全区) | Ref<View> | - |
类型
import type { NavBarProps, NavBarSlots } from '@skyroc/native-ui';NavBarSlots
可通过 classNames 覆盖的 slot 名称。
SlotClassNames
classNames 的取值形态:把 slot 名映射到类名,每个 slot 都可选。本页用到的 slot 见 NavBarSlots。
包内还导出了 navBarVariants。