# HyperOS 组件库架构

> HyperOS 组件库知识库，覆盖 `src/hyperOS` 的目录结构、公共导出、组件分层、核心模式、按需加载与维护规则。

## 概览

`mhui-rn` 的 HyperOS 组件体系是米家 React Native UI 组件库当前活跃开发的设计系统，运行环境基于 React 16.9、React Native 0.61 和 TypeScript 3.8，公共 API 从 `src/hyperOS/index.ts` 导出。

## 技术栈

| 项 | 当前版本 |
|---|---|
| React | 16.9 |
| React Native | 0.61 |
| TypeScript | 3.8 |
| Babel | 7.x |
| Jest | 25/26 体系配置 |
| ESLint | Airbnb + Prettier + React Hooks + React Native |

## 目录结构

```text
src/
  hyperOS/
    components/          # 基础 UI 组件目录，含 actionSheet、dialog、navigationBar、listItem 等
    IotComponents/       # IoT 场景组件目录，含 statusAlert、slider、stepper、entrance 等
    layoutComponents/    # 页面布局组件，PageLayout / SubpageLayout
    styles/              # HyperOS Token，含 color / fonts / radius / space / Styles.ts
    index.ts             # HyperOS 公共导出入口
  constants/             # HyperOS 组件使用的全局常量，如 iconsConfig、layout、font
  icons/                 # HyperOS 可复用 SVG 图标组件
  hooks/                 # HyperOS 组件使用的公共 hooks，如 useCollapsibleTitle
  utils/                 # HyperOS 组件使用的无障碍、颜色、尺寸、日志等工具
```

当前 `src/hyperOS` 下的主要目录数量：

| 目录 | 数量 | 说明 |
|---|---:|---|
| `components` | 28 个目录 | 基础组件、弹窗、导航、输入、菜单、列表等 |
| `IotComponents` | 17 个目录 | IoT 控制卡片、告警、滑杆、步进器、入口、图文按钮等 |
| `layoutComponents` | 2 个目录 | `PageLayout`、`SubpageLayout` |
| `styles` | 4 个目录 | `color`、`fonts`、`radius`、`space` |

## 组件分层

| 层级 | 说明 | 代表组件 |
|---|---|---|
| **基础组件** `src/hyperOS/components` | 通用 UI 原子/基础复合组件，不绑定具体设备业务 | `Button`、`Switch`、`ListItem`、`Dialog`、`NavigationBar`、`Input`、`NoticeBar` |
| **IoT 组件** `src/hyperOS/IotComponents` | 面向设备控制、设备状态与 IoT 卡片场景的组件 | `StatusAlert`、`Slider`、`Stepper`、`CardHeader`、`DataItem`、`MediumImageButton` |
| **布局组件** `src/hyperOS/layoutComponents` | 页面级布局容器，处理滚动区、底部安全区、slot 组合 | `PageLayout`、`SubpageLayout` |
| **设计 Token** `src/hyperOS/styles` | 颜色、字体、圆角、间距与通用类型 | `colorToken`、`radiusToken`、`Fonts`、`spaceToken` |

## 公共导出

HyperOS 公共 API 由 `src/hyperOS/index.ts` 控制，按需加载映射由 `importMap.js` 控制。新增、删除或重命名组件时必须同步检查这两处。

主要公共导出包括：

- 基础组件：`Button`、`BlockButton`、`ButtonGroup`、`Switch`、`Checkbox`、`Radio`、`ListItem`、`ListItemWithWidget`、`ActionListItem`、`ListCard`、`Drawer`、`NavigationBar`、`ActionSheet`、`Input`、`NoticeBar`、`SegmentedControls`、`SelectList`、`PopMenus`、`Menus`、`LoadingToast`、`PullRefresh`、`Spin`、`Badge` 等。
- Dialog 体系：`CommonDialog`、`MessageDialog`、`ActionCustomDialog`、`InputDialog`、`CustomDialog`、`PickerDialog`。
- IoT 组件：`StatusAlert`、`Slider`、`SliderWithToggle`、`Stepper`、`CardHeader`、`CardContainer`、`ContainerWithGap`、`DataItem`、`DataGroup`、`ActionBlock`、`LargeTriggerSelect`、`MediumTriggerSelect`、`LargeListEntrance`、`MediumListEntrance`、`SmallGridEntrance`、`LargeListToggle`、`MediumListToggle`、`SmallGridToggle`、`MediumImageButton`、`SmallImageButton`、`CircularButton`、`SmallGridContainer`。
- 布局组件：`PageLayout`、`SubpageLayout`。
- Token / 配置：`colorToken`、`defaultColorToken`、`radiusToken`、`Fonts`、`spaceToken`、`ConfigContext`、`ConfigProvider`、`defaultTheme`。
- 工具导出：`showToast`、`useCollapsibleTitle`。

部分目录存在但不是 HyperOS 公共 API，例如 `Shadow`、`TouchCbView` 等，使用前应先确认是否已从 `src/hyperOS/index.ts` 导出。

## 核心模式

### 颜色系统

组件通过 `ConfigContext` 获取 `colorToken`，避免直接写死色值：

```tsx
const { colorToken } = useContext(ConfigContext);
```

状态色、主题色和禁用色应优先使用语义 Token，例如：

- 内容色：`contentPrimaryNormal`、`contentSecondaryNormal`、`contentDisabledPrimary`
- 背景色：`surfacePageLow`、`surfaceCardPrimary`、`surfaceCardModal`
- 强调色：`accentBlueFill`、`accentRedFill` 等

色系变体通过 `useColorTypeState` / `useBackGroundColorTypeState` 处理，`ColorType` 定义在 `src/hyperOS/styles/Styles.ts`。

### 字体与平台差异

字体 Token 位于 `src/hyperOS/styles/fonts`。iOS 系统字体场景应尽量避免写入 `fontFamily: 'sans-serif'`，Android 可按需要使用 `sans-serif` / `sans-serif-medium`。数字字体 Token 仅建议用于纯数字内容，混排中文会触发系统 fallback。

### 底部安全区

布局组件的底部补偿依赖 `src/constants/layout.ts`：

- `LAYOUT_BOTTOM_PADDING_OFFSET`：Android 为 28，iOS 为 0。
- `LAYOUT_SAFE_BOTTOM_FALLBACK`：iOS 兜底 34，Android 兜底 0。
- `LAYOUT_DEFAULT_BOTTOM_PADDING`：兜底安全区与平台补偿之和。

`PageLayout` 和 `SubpageLayout` 读取 `getSafeAreaInsets()` 成功时使用真实 `bottom`，失败或缺失时使用平台兜底。

### 无障碍

组件无障碍配置通过 `getAccessibilityConfig()` 和 `AccessibilityPropsType` / `IAccessibilityPropTypes` 统一处理。复合组件中标题、副标题、右侧文案等子区域通常会提供独立的 `accessibilityTitle`、`accessibilitySubtitle`、`accessibilityText` 等配置。

### 按压态

HyperOS 新组件按压交互应使用统一封装：

- `TouchableView`：普通按压态。
- `TouchCbView`：需要通过 render prop 获取按压状态时使用。

避免直接使用 RN 原生 `TouchableOpacity`、`TouchableHighlight`、`Pressable` 实现新组件交互；禁用态也不要通过 `opacity` 降透明度，应使用 disabled 语义色。

### 组件上报

组件通常在首次挂载时调用 `referenceReport('组件名')`：

```tsx
useEffect(() => {
  referenceReport('ComponentName');
}, []);
```

### Dialog 体系

当前 Dialog 公共导出包括：

```text
BaseDialog（内部基础壳：Modal + 动画 + 标题 + ButtonGroup + children）
  ├── CommonDialog
  ├── MessageDialog
  ├── ActionCustomDialog
  ├── InputDialog
  ├── CustomDialog
  └── PickerDialog
```

`BaseDialog` 本身不是 `src/hyperOS/index.ts` 的公共导出，但通过 `components/dialog` 目录内部复用。`LoadingToast` 在独立目录 `components/loadingToast`。`PopMenus` 和 `Menus` 是独立菜单组件，不属于 Dialog 继承链。

## 按需加载

React Native 0.61 的 Metro 不做有效 tree-shaking，消费侧需要配合 `babel-plugin-import` 与 `importMap.js` 做按需加载：

```js
const mhuiImportMap = require('mhui-rn/importMap');

['import', {
  libraryName: 'mhui-rn',
  camel2DashComponentName: false,
  customName: name => mhuiImportMap[name] || `mhui-rn/dist/hyperOS/components/${name}`,
}, 'mhui-rn'];
```

维护规则：

- 新增公共组件：同步 `src/hyperOS/index.ts`、组件目录 `index.ts(x)`、`importMap.js`。
- 新增类型公共导出：从对应目录导出 type，并确认是否需要在 `src/hyperOS/index.ts` 暴露。
- 新增 demo 消费入口：同步 demo 项目的 SDK barrel 文件。

## 路径别名

`baseUrl` 为 `src/`，以下别名需要在 `tsconfig.json`、`babel.config.js`、`jest.config.js`、`.eslintrc.js` 中保持一致：

| 别名 | 路径 |
|---|---|
| `@components/*` | `src/components/*` |
| `@hyperOS/*` | `src/hyperOS/*` |
| `@styles/*` | `src/styles/*` |
| `@utils/*` | `src/utils/*` |
| `@icons/*` | `src/icons/*` |
| `@constants/*` | `src/constants/*` |
| `@decorators/*` | `src/decorators/*` |
| `@locale/*` | `src/locale/*` |
| `@modules/*` | `src/modules/*` |
| `@resources/*` | `src/resources/*` |

## 命名规范

| 场景 | 推荐命名 |
|---|---|
| 开关状态 | `checked` |
| 状态变化回调 | `onChange` |
| 左侧图标 | `leadingIcon` |
| 红点标记 | `badge` / `showDot`（NavigationBar 按钮配置中使用 `showDot`） |
| 右侧文案 | `value` |
| 自定义渲染 | `customRender` |
| 右侧操作类型 | `actionType` |
| 禁用状态 | `disabled` / NavigationBar 按钮配置中为 `disable` |

## 测试与文档

- 单测目录：新组件使用 `__tests__`。
- 新组件测试优先使用 `@testing-library/react-native`。
- 组件 API 类型必须放在组件目录的 `interface.ts`。
- 组件文档放在组件目录下的 `{ComponentName}.zh-CN.md` 或 `index.zh-CN.md`。
- 聚合知识库文档可从 `src/hyperOS/**/*.zh-CN.md` 生成，具体组件 API 以组件目录文档和 `interface.ts` 为准。

## AI 排查速查

| 问题 | 排查入口 |
|---|---|
| 组件无法从包入口导入 | 检查 `src/hyperOS/index.ts` 是否导出 |
| 按需加载路径不对 | 检查 `importMap.js` |
| Props 类型和文档不一致 | 以组件目录 `interface.ts` 为准 |
| 颜色不跟随主题 | 检查是否通过 `ConfigContext` 使用 `colorToken` |
| RN 0.61 布局异常 | 避免使用 `gap`，用 margin 方案替代 |
| RTL 图标方向问题 | 检查方向图标是否使用 `I18nManager.isRTL` 做旋转 |
| 底部安全区异常 | 检查 `src/constants/layout.ts` 与 `getSafeAreaInsets()` 兜底逻辑 |
