# Header

`Header` 组件为 Blocklet 应用提供了一个响应式且可定制的页眉。它通过直接从 blocklet 的配置（`blocklet.yml`）中读取元数据，自动填充导航链接、应用 logo 和用户会话控件。该组件旨在以最少的配置创建一个功能丰富且一致的页眉。

## 概述

`Header` 组件是主要的导航和品牌元素。它构建于 `@arcblock/ux` 组件之上，包括 `ResponsiveHeader` 和 `NavMenu`，并与用于用户身份验证的 DID Connect 会话上下文无缝集成。

主要功能包括：
- **自动配置**：从 `blocklet.yml` 中填充应用 logo、标题和导航链接。
- **响应式设计**：自动适应不同的屏幕尺寸，提供移动设备友好的导航菜单。
- **会话管理**：与 DID Connect 集成，以显示用户信息、个人资料菜单以及登录/登出按钮。
- **可定制的插件**：允许注入自定义组件或修改默认元素，如主题切换器和语言选择器。
- **组织切换**：如果 blocklet 启用了组织支持，则自动包含一个组织切换器。
- **域名警告**：当管理员和用户通过临时域名访问应用时，通知他们配置自定义域名以提高安全性。

### 工作原理

下图说明了 `Header` 的数据流和组件构成。它从 `blocklet.yml` 文件中读取配置，进行处理，并渲染相应的 UI 元素，包括 logo、导航链接和用户会话控件。

<!-- DIAGRAM_IMAGE_START:architecture:16:9:1765962229 -->
![Header](assets/diagram/header-diagram-0.zh.jpg)
<!-- DIAGRAM_IMAGE_END -->

## 基本用法

要使用 `Header`，请将其导入并放置在应用的布局中。它需要 blocklet 的元数据，该元数据通常通过 `window.blocklet` 全局可用。

```javascript "App.js" icon=logos:javascript
import Header from '@blocklet/ui-react/lib/Header';

function App() {
  // meta 对象通常来源于 window.blocklet
  const blockletMeta = window.blocklet || {};

  return (
    <div>
      <Header meta={blockletMeta} />
      <main>
        {/* 你的应用内容 */}
      </main>
    </div>
  );
}

export default App;
```

## Props

`Header` 组件接受多个 props 以进行自定义。

<x-field-group>
  <x-field data-name="meta" data-type="BlockletMetaProps" data-required="false">
    <x-field-desc markdown="blocklet 的元数据对象，通常来自 `window.blocklet`。它包含组件用于渲染的信息，如 `name`、`logo` 和 `navigation`。"></x-field-desc>
  </x-field>
  <x-field data-name="addons" data-type="Function | React.ReactNode" data-required="false">
    <x-field-desc markdown="要添加到页眉右侧的自定义元素。如果提供一个函数，它会接收内置插件作为参数，允许您修改、重新排序或补充它们。如果提供一个节点，它将替换所有内置插件。"></x-field-desc>
  </x-field>
  <x-field data-name="sessionManagerProps" data-type="SessionManagerProps" data-required="false" data-default='{ "showRole": true }'>
    <x-field-desc markdown="直接传递给底层 `SessionUser` 组件的 props，用于控制用户会话信息的显示，例如显示用户角色。"></x-field-desc>
  </x-field>
  <x-field data-name="homeLink" data-type="string | Function" data-required="false" data-default="publicPath">
    <x-field-desc markdown="主页链接的 URL，通常通过点击 logo 或品牌名称触发。它默认为 blocklet 的公共路径（`/`）。也可以是一个返回 JSX 元素的函数。"></x-field-desc>
  </x-field>
  <x-field data-name="theme" data-type="object" data-required="false">
    <x-field-desc markdown="一个 Material-UI 主题对象，用于与默认主题合并，从而实现对颜色、排版和其他样式的深度自定义。"></x-field-desc>
  </x-field>
  <x-field data-name="hideNavMenu" data-type="boolean" data-required="false" data-default="false">
    <x-field-desc markdown="如果为 `true`，即使存在导航数据，从 `blocklet.yml` 生成的导航菜单也将被隐藏。"></x-field-desc>
  </x-field>
  <x-field data-name="bordered" data-type="boolean" data-required="false" data-default="false">
    <x-field-desc markdown="如果为 `true`，将在页眉底部应用一条边框以进行视觉分隔。"></x-field-desc>
  </x-field>
  <x-field data-name="logo" data-type="React.ReactNode" data-required="false">
    <x-field-desc markdown="一个自定义 logo 元素，用于覆盖来自 blocklet 元数据的 logo。"></x-field-desc>
  </x-field>
  <x-field data-name="brand" data-type="React.ReactNode" data-required="false">
    <x-field-desc markdown="一个自定义品牌元素（例如，文本或图像），显示在 logo 旁边。"></x-field-desc>
  </x-field>
  <x-field data-name="showDomainWarningDialog" data-type="boolean" data-required="false" data-default="true">
    <x-field-desc markdown="如果为 `false`，则不会显示关于临时域名的警告对话框。"></x-field-desc>
  </x-field>
</x-field-group>

## 功能

### 从元数据自动生成导航

`Header` 会根据 `blocklet.yml` 文件中的 `navigation` 数组自动生成其导航菜单。该组件解析此配置以创建主导航链接和嵌套的下拉菜单。

以下是 `blocklet.yml` 中 `navigation` 配置的示例：

```yaml "blocklet.yml" icon=mdi:code-braces
navigation:
  - title: Features
    link: /features
    icon: 'mdi:star'
  - title: Docs
    link: /docs
    icon: 'mdi:book-open'
  - title: More
    items:
      - title: About Us
        link: /about
        description: Learn more about our mission.
      - title: Community
        link: https://community.example.com
        description: Join our community forum.
```

`parseNavigation` 工具程序会处理此结构，处理 `title` 和 `description` 的本地化，并根据当前 URL 路径确定活动链接。

### 会话管理和插件

页眉的右侧包含“插件”，这是一组用于会话管理和应用设置的控件。默认情况下，这些插件包括：

- **组织切换器**：如果 blocklet 启用了组织支持，则会出现。
- **通知中心**：如果 blocklet 包含通知页面，则会出现。
- **语言选择器**：如果配置了多种语言，则会出现。
- **主题模式切换器**：在亮色和暗色模式之间切换。
- **会话控件**：显示已登录用户的头像和一个包含个人资料、设置和登出链接的菜单。对于访客，它会显示一个“连接钱包”按钮。

#### 自定义插件

您可以使用 `addons` prop 来自定义这些插件。

**示例：追加一个自定义按钮**

向 `addons` prop 提供一个函数。此函数接收一个包含默认插件元素的数组，允许您添加自己的元素。

```javascript "HeaderWithCustomAddon.js" icon=logos:javascript
import Header from '@blocklet/ui-react/lib/Header';
import Button from '@mui/material/Button';

function HeaderWithCustomAddon() {
  return (
    <Header
      meta={window.blocklet}
      addons={(builtInAddons) => (
        <>
          {builtInAddons}
          <Button variant="contained" color="primary" sx={{ ml: 1 }}>
            Upgrade
          </Button>
        </>
      )}
    />
  );
}
```

**示例：替换所有插件**

提供一个 React 节点或节点数组来完全替换默认插件。

```javascript "HeaderWithReplacedAddons.js" icon=logos:javascript
import Header from '@blocklet/ui-react/lib/Header';
import Button from '@mui/material/Button';

function HeaderWithReplacedAddons() {
  return (
    <Header
      meta={window.blocklet}
      addons={[
        <Button key="feedback" variant="outlined" sx={{ ml: 1 }}>
          Feedback
        </Button>,
      ]}
    />
  );
}
```

### 在嵌入模式下隐藏

`Header` 被 `withHideWhenEmbed` 高阶组件包裹。当应用在嵌入式上下文（例如，在 `sessionStorage` 包含 `EMBED_MODE_KEY: 1` 的 iframe 中）渲染时，它将自动隐藏。当您的 blocklet 集成到另一个应用中时，这对于提供更简洁的 UI 非常有用。

## 总结

`Header` 组件是在 Blocklet 应用中建立一致品牌和导航的强大工具。通过利用 blocklet 元数据，它简化了开发过程，同时通过 props 提供了广泛的自定义选项。

有关相关的布局组件，请参阅 [Footer](./components-layout-footer.md) 的文档。