# NavigationBar - 导航栏

## 说明

页面顶部导航栏，提供标题展示、左右图标按钮、品牌 logo 展示。支持 `normal`（居中标题）和 `large`（左对齐大标题）两种尺寸。配合 `useCollapsibleTitle` hook 可实现滚动折叠大标题效果。

## 属性

| 属性 | 说明 | 类型 | 默认值 | 必填 |
|------|------|------|--------|------|
| **title** | 标题文案或自定义元素 | `string \| ReactElement` | - | 否 |
| **titleSize** | 标题尺寸 | `'normal' \| 'large'` | `'normal'` | 否 |
| **showBrandLogo** | 是否展示品牌 logo（仅 titleSize=normal 时生效） | `boolean` | `false` | 否 |
| **isRounded** | 是否为品牌 logo 添加圆角描边，仅 `showBrandLogo=true` 且品牌图加载成功时生效；**v1.18.20（待发布）新增** | `boolean` | `false` | 否 |
| **left** | 左侧按钮配置 | `LeftButtonConfig` | `{ key: 'back' }` | 否 |
| **right** | 右侧配置，支持标准图标按钮和自定义内容；自定义内容能力为 **v1.18.20（待发布）新增** | `RightButtonConfig` | - | 否 |
| **colorStrategy** | 沉浸模式主题 | `'auto' \| 'forceDark'` | `'auto'` | 否 |
| **backgroundColor** | 自定义背景色 | `string` | `'transparent'` | 否 |
| **collapseTitle** | 启用折叠标题模式，仅 `titleSize='large'` 时生效 | `boolean` | `false` | 否 |
| **titleVisible** | 顶部标题是否显示，仅 `collapseTitle=true` 时生效 | `boolean` | `false` | 否 |
| **titleOpacity** | 顶部标题透明度（0-1），仅 `collapseTitle=true` 时生效，优先级高于 titleVisible | `number \| Animated.AnimatedInterpolation` | - | 否 |

### LeftButtonConfig / RightButtonConfig

| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| **key** | 右侧类型；标准图标传图标 key，自定义内容传 `custom`（**v1.18.20（待发布）新增**） | `string` | - |
| **onPress** | 点击回调 | `() => void` | - |
| **disable** | 是否禁用 | `boolean` | `false` |
| **showDot** | 是否显示小红点 | `boolean` | `false` |
| **customRender** | 自定义右侧渲染内容，仅 `key='custom'` 时生效；**v1.18.20（待发布）新增** | `ReactElement` | - |

## 使用示例

```tsx
import React from 'react';
import { Text } from 'react-native';
import { NavigationBar, TouchableView } from 'mhui-rn';

// 基本用法
<NavigationBar title="设备详情" left={{ key: 'back', onPress: () => navigation.goBack() }} />

// 大标题
<NavigationBar title="我的设备" titleSize="large" />

// 右侧更多按钮
<NavigationBar
  title="设置"
  left={{ key: 'back', onPress: goBack }}
  right={{ key: 'more', onPress: showMenu }}
/>

// 右侧自定义内容
<NavigationBar
  title="设备"
  right={{
    key: 'custom',
    customRender: (
      <TouchableView onPress={openSettings}>
        <Text>设置</Text>
      </TouchableView>
    ),
  }}
/>

// 强制深色模式
<NavigationBar title="相机" colorStrategy="forceDark" />

// 品牌 logo 使用圆角描边
<NavigationBar title="米家" showBrandLogo isRounded />

// 品牌 logo 不使用圆角描边
<NavigationBar title="米家" showBrandLogo isRounded={false} />
```

## 滚动折叠标题

配合 `useCollapsibleTitle` hook 和 `PageLayout` 实现大标题滚动折叠效果。初始显示大标题（LargeTitle），滚动时大标题渐隐消失，NavigationBar 顶部标题渐显。

### 方式一：NavigationBar 在 PageLayout 内部（推荐）

NavigationBar 放在 `PageLayout.Navigation` slot 中，Background 可覆盖整个区域。

```tsx
import { NavigationBar, PageLayout, useCollapsibleTitle } from 'mhui-rn';

function DevicePage() {
  const { scrollHandler, titleVisible, titleOpacity, LargeTitle } = useCollapsibleTitle({
    title: '设备名称',
  });

  return (
    <PageLayout onScroll={scrollHandler}>
      <PageLayout.Background>
        <View style={{ height: 260, backgroundColor: '#E5F0FF' }} />
      </PageLayout.Background>

      <PageLayout.Navigation>
        <NavigationBar
          title="设备名称"
          titleSize="large"
          collapseTitle
          titleVisible={titleVisible}
          titleOpacity={titleOpacity}
          showBrandLogo
          left={{ key: 'back', onPress: goBack }}
          right={{ key: 'more', onPress: showMenu }}
        />
      </PageLayout.Navigation>

      <PageLayout.Header>
        <LargeTitle />
      </PageLayout.Header>

      <PageLayout.Content>
        {/* 页面内容 */}
      </PageLayout.Content>
    </PageLayout>
  );
}
```

### 方式二：NavigationBar 由 react-native-navigation 统一管理

通过 `navigation.setParams` 动态传递折叠参数给统一 NavigationBar。

```tsx
import { SubpageLayout, useCollapsibleTitle } from 'mhui-rn';

function SettingsPage({ navigation }) {
  const { scrollHandler, titleVisible, titleOpacity, LargeTitle } = useCollapsibleTitle({
    title: '高级设置',
  });

  useEffect(() => {
    navigation.setParams({
      title: '高级设置',
      titleSize: 'large',
      collapseTitle: true,
      titleVisible: false,
      titleOpacity: 0,
    });
  }, []);

  useEffect(() => {
    navigation.setParams({ titleVisible, titleOpacity });
  }, [titleVisible, titleOpacity]);

  return (
    <SubpageLayout onScroll={scrollHandler}>
      <SubpageLayout.Header>
        <LargeTitle />
      </SubpageLayout.Header>
      <SubpageLayout.Content>
        {/* 页面内容 */}
      </SubpageLayout.Content>
    </SubpageLayout>
  );
}
```

### useCollapsibleTitle 参数

| 参数 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| **title** | 大标题内容 | `string \| ReactElement` | - |
| **threshold** | 触发折叠的滚动阈值（px），不传则自动测量大标题高度 | `number` | 自动 |

### useCollapsibleTitle 返回值

| 字段 | 说明 | 类型 |
|------|------|------|
| **scrollHandler** | 传给 Layout 的 onScroll，pad 端为 undefined | `((...args) => void) \| undefined` |
| **titleVisible** | 大标题是否已滚出视口 | `boolean` |
| **titleOpacity** | NavigationBar 标题透明度（0→1 渐显），pad 端为 undefined | `Animated.AnimatedInterpolation \| undefined` |
| **LargeTitle** | 放入 Layout.Header 的大标题组件（带渐隐动画），pad 端渲染为 null | `React.FC` |

## 注意事项

- `titleSize='large'` 在 iPad 上会降级为 `normal`，`collapseTitle`/`titleVisible`/`titleOpacity` 不生效
- `useCollapsibleTitle` 在 iPad 上自动跳过所有动画计算，`LargeTitle` 返回 null，`scrollHandler` 返回 undefined
- `showBrandLogo` 在 `collapseTitle` 模式下，标题显示时会展示品牌 logo（复用 normal 模式的标题渲染）
- 品牌 logo 使用 `contain` 模式渲染，避免因默认 `cover` 模式裁切图片内容；圆角模式使用透明容器负责边框与裁切，图片内容使用内层圆角渲染
- `isRounded` 只控制品牌 logo 的圆角描边，默认值为 `false`；为 `true` 时使用 20 × 20、1px 边框和 5px 圆角的透明容器，内部图片为 18 × 18、4px 圆角，不使用背景色模拟描边
- 品牌 logo 与标题同时展示时，标题通过通用 Flex 居中规则与品牌图保持视觉对齐，不区分 iOS 和 Android
- `titleOpacity` 优先级高于 `titleVisible`：传了 `titleOpacity` 时标题始终渲染，通过透明度控制显隐
- `right.key='custom'` 时通过 `customRender` 提供右侧内容，组件不会额外包裹点击容器；自定义内容的点击和无障碍行为由调用方负责
- 通过 `NavigationBar.ICON` 获取 key 常量（BACK / CANCEL / CONFIRM / MORE / CUSTOM）
- `LargeTitle` 组件样式与 NavigationBar 内部大标题一致（fontSystem32Regular，左对齐，最多 3 行）
