Skip to content

Header

Telegram Mini Apps 2.0 风格的 Header 组件,支持两种变体:Default (iOS 白色背景) 和 Fullscreen (玻璃态)。

特性

  • 🎨 两种变体:Default (iOS 风格) 和 Fullscreen (玻璃态全屏)
  • 📐 Flexbox 布局:使用现代 Flexbox 布局,自动处理左、中、右区域
  • 🎯 完整标题支持:两种变体都支持标题和副标题显示
  • 🎭 高度可定制:提供完整的 CSS Token 变量体系
  • 🌈 背景透明:默认透明背景,支持自定义任何颜色或渐变

导入

tsx
import { Header } from '@xcloud/ui-mobile'

示例

Default 变体

iOS 风格的白色背景 Header,适合常规页面使用。

基础用法

tsx
import { Header } from '@xcloud/ui-mobile'

function Page() {
  return (
    <Header
      variant="default"
      title="页面标题"
      leftButton={{
        type: 'back',
        label: '返回',
        onClick: () => console.log('返回')
      }}
    />
  )
}

标题 + 副标题

tsx
<Header
  variant="default"
  title="主标题"
  subtitle="副标题信息"
  leftButton={{
    type: 'back',
    label: '返回',
    onClick: () => console.log('返回')
  }}
  rightButtons={[
    { type: 'more', onClick: () => console.log('更多') }
  ]}
/>

自定义主题

通过 CSS 变量自定义样式:

tsx
<Header
  variant="default"
  title="深色模式"
  subtitle="使用 CSS 变量自定义"
  leftButton={{
    type: 'back',
    label: '返回',
    onClick: () => console.log('返回')
  }}
  style={{
    '--xc-header-default-content-bg': '#1f2937',
    '--xc-header-default-title-color': '#ffffff',
    '--xc-header-default-subtitle-color': '#9ca3af',
    '--xc-header-default-button-color': '#60a5fa'
  }}
/>

自定义右侧内容

不使用胶囊按钮,而是自定义右侧内容:

tsx
import { Header } from '@xcloud/ui-mobile'
import { Bell, Search } from 'lucide-react'

<Header
  variant="default"
  title="消息中心"
  leftButton={{
    type: 'back',
    onClick: () => console.log('返回')
  }}
  rightContent={
    <div style={{ display: 'flex', gap: '8px' }}>
      <button onClick={() => console.log('搜索')}>
        <Search size={20} />
      </button>
      <button onClick={() => console.log('通知')}>
        <Bell size={20} />
      </button>
    </div>
  }
/>

Fullscreen 变体

玻璃态全屏风格的 Header,适合沉浸式页面使用。

基础用法

tsx
<Header
  variant="fullscreen"
  title="全屏标题"
  subtitle="副标题信息"
  leftButton={{
    type: 'back',
    label: '返回',
    onClick: () => console.log('返回')
  }}
  rightButtons={[
    { type: 'more', onClick: () => console.log('更多') },
    { type: 'close', onClick: () => console.log('关闭') }
  ]}
/>

自定义玻璃态按钮

tsx
<Header
  variant="fullscreen"
  title="自定义按钮样式"
  leftButton={{
    type: 'back',
    label: '返回',
    onClick: () => console.log('返回')
  }}
  style={{
    '--xc-header-fullscreen-button-bg': 'rgba(255, 255, 255, 0.2)',
    '--xc-header-fullscreen-button-bg-hover': 'rgba(255, 255, 255, 0.3)',
    '--xc-header-fullscreen-button-color': '#ffffff'
  }}
/>

自定义右侧内容(Fullscreen)

在全屏模式下使用自定义右侧内容:

tsx
import { Header } from '@xcloud/ui-mobile'
import { Share2, Heart } from 'lucide-react'

<Header
  variant="fullscreen"
  title="图片详情"
  leftButton={{
    type: 'back',
    onClick: () => console.log('返回')
  }}
  rightContent={
    <div style={{ display: 'flex', gap: '12px' }}>
      <button
        onClick={() => console.log('收藏')}
        style={{
          background: 'rgba(255, 255, 255, 0.2)',
          backdropFilter: 'blur(10px)',
          border: 'none',
          borderRadius: '20px',
          padding: '8px 16px',
          color: 'white',
          display: 'flex',
          alignItems: 'center',
          gap: '6px'
        }}
      >
        <Heart size={18} />
      </button>
      <button
        onClick={() => console.log('分享')}
        style={{
          background: 'rgba(255, 255, 255, 0.2)',
          backdropFilter: 'blur(10px)',
          border: 'none',
          borderRadius: '20px',
          padding: '8px 16px',
          color: 'white',
          display: 'flex',
          alignItems: 'center',
          gap: '6px'
        }}
      >
        <Share2 size={18} />
      </button>
    </div>
  }
/>

固定定位的全屏 Header(内容穿透)

当需要 Header 固定在容器顶部,内容可以滚动穿透到 Header 下方时:

tsx
<Header
  variant="fullscreen"
  title="长页面滚动"
  subtitle="Header 固定,内容穿透"
  leftButton={{
    type: 'back',
    label: '返回',
    onClick: () => console.log('返回')
  }}
  style={{
    '--xc-header-fullscreen-position': 'absolute',
    '--xc-header-fullscreen-top': '0',
    '--xc-header-fullscreen-left': '0',
    '--xc-header-fullscreen-right': '0',
    '--xc-header-fullscreen-z-index': '1000'
  }}
/>

属性

HeaderProps

属性类型默认值描述
titlestring-标题文本
subtitlestring-副标题文本
leftButtonHeaderButton-左侧按钮配置
showCapsulebooleantrue是否显示右侧胶囊按钮
onAboutClick() => void-胶囊"关于"按钮点击回调
onCloseClick() => void-胶囊"关闭"按钮点击回调
rightContentReact.ReactNode-右侧自定义内容。如果设置了此属性,将忽略 showCapsule 和胶囊相关配置
variant'default' | 'fullscreen''default'变体类型
iosbooleantrueiOS 样式
classNamestring-自定义类名
styleReact.CSSProperties-自定义样式(支持 CSS 变量)

HeaderButton

属性类型描述
typeHeaderButtonType按钮类型:'close' | 'back' | 'more' | 'collapse' | 'custom' | 'null'
iconReact.ComponentType<any>自定义图标组件
labelstring按钮文本标签
onClick() => void点击处理函数

CSS Tokens

Default 变体 (浅色模式)

css
/* 背景和布局 */
--xc-header-default-bg: transparent
--xc-header-default-backdrop-blur: 25px
--xc-header-default-content-bg: #ffffff
--xc-header-default-padding-y: 4px
--xc-header-default-padding-x: 8px
--xc-header-default-gap: 8px

/* 标题样式 */
--xc-header-default-title-color: #000000
--xc-header-default-title-size: 17px
--xc-header-default-title-weight: 600

/* 副标题样式 */
--xc-header-default-subtitle-color: #707579
--xc-header-default-subtitle-size: 13px

/* 按钮样式 */
--xc-header-default-button-color: rgba(0, 0, 0, 0.8)
--xc-header-default-button-active-opacity: 0.6

Default 变体 (暗黑模式 - 需要 .dark 类)

css
/* 背景和布局 */
--xc-header-dark-default-bg: transparent
--xc-header-dark-default-backdrop-blur: 25px
--xc-header-dark-default-content-bg: #1c1c1e
--xc-header-dark-default-padding-y: 4px
--xc-header-dark-default-padding-x: 8px
--xc-header-dark-default-gap: 8px

/* 标题样式 */
--xc-header-dark-default-title-color: #ffffff
--xc-header-dark-default-title-size: 17px
--xc-header-dark-default-title-weight: 600

/* 副标题样式 */
--xc-header-dark-default-subtitle-color: #98989d
--xc-header-dark-default-subtitle-size: 13px

/* 按钮样式 */
--xc-header-dark-default-button-color: #98989d
--xc-header-dark-default-button-active-opacity: 0.6

Fullscreen 变体 (浅色模式)

css
/* 背景和布局 */
--xc-header-fullscreen-bg: transparent
--xc-header-fullscreen-position: relative
--xc-header-fullscreen-top: auto
--xc-header-fullscreen-left: auto
--xc-header-fullscreen-right: auto
--xc-header-fullscreen-z-index: auto
--xc-header-fullscreen-padding: 16px
--xc-header-fullscreen-gap: 10px

/* 标题样式 */
--xc-header-fullscreen-title-color: #ffffff
--xc-header-fullscreen-title-size: 17px
--xc-header-fullscreen-title-weight: 600

/* 副标题样式 */
--xc-header-fullscreen-subtitle-color: rgba(255,255,255,0.7)
--xc-header-fullscreen-subtitle-size: 13px

/* 玻璃态按钮样式 */
--xc-header-fullscreen-button-bg: rgba(255,255,255,0.2)
--xc-header-fullscreen-button-bg-hover: rgba(65,63,64,0.5)
--xc-header-fullscreen-button-bg-active: rgba(65,63,64,0.6)
--xc-header-fullscreen-button-color: #ffffff
--xc-header-fullscreen-button-blur: 5px
--xc-header-fullscreen-button-radius: 32px

Fullscreen 变体 (暗黑模式 - 需要 .dark 类)

css
/* 背景和布局 */
--xc-header-dark-fullscreen-bg: transparent
--xc-header-dark-fullscreen-position: relative
--xc-header-dark-fullscreen-top: auto
--xc-header-dark-fullscreen-left: auto
--xc-header-dark-fullscreen-right: auto
--xc-header-dark-fullscreen-z-index: auto
--xc-header-dark-fullscreen-padding: 16px
--xc-header-dark-fullscreen-gap: 10px

/* 标题样式 */
--xc-header-dark-fullscreen-title-color: #ffffff
--xc-header-dark-fullscreen-title-size: 17px
--xc-header-dark-fullscreen-title-weight: 600

/* 副标题样式 */
--xc-header-dark-fullscreen-subtitle-color: rgba(255,255,255,0.7)
--xc-header-dark-fullscreen-subtitle-size: 13px

/* 玻璃态按钮样式 */
--xc-header-dark-fullscreen-button-bg: rgba(255,255,255,0.15)
--xc-header-dark-fullscreen-button-bg-hover: rgba(255,255,255,0.25)
--xc-header-dark-fullscreen-button-bg-active: rgba(255,255,255,0.35)
--xc-header-dark-fullscreen-button-color: #ffffff
--xc-header-dark-fullscreen-button-blur: 5px
--xc-header-dark-fullscreen-button-radius: 32px

胶囊按钮 (浅色模式)

css
/* 基础样式 */
--xc-header-capsule-height: 32px
--xc-header-capsule-bg: rgba(255,255,255,0.02)  /* default变体 */
--xc-header-capsule-bg: rgba(255,255,255,0.2)   /* fullscreen变体 */
--xc-header-capsule-border-width: 1px
--xc-header-capsule-border-color: rgba(0,0,0,0.04)      /* default变体 */
--xc-header-capsule-border-color: rgba(255,255,255,0.3) /* fullscreen变体 */
--xc-header-capsule-radius: 16px
--xc-header-capsule-blur: 10px

/* 按钮样式 */
--xc-header-capsule-button-padding-x: 12px
--xc-header-capsule-button-color: rgba(0,0,0,0.8)  /* default变体 */
--xc-header-capsule-button-color: #ffffff          /* fullscreen变体 */
--xc-header-capsule-icon-size: 16px
--xc-header-capsule-transition-duration: 200ms

/* 交互状态 */
--xc-header-capsule-button-hover-bg: rgba(0,0,0,0.02)      /* default变体 */
--xc-header-capsule-button-hover-bg: rgba(255,255,255,0.1) /* fullscreen变体 */
--xc-header-capsule-button-active-bg: rgba(0,0,0,0.12)     /* default变体 */
--xc-header-capsule-button-active-bg: rgba(255,255,255,0.2) /* fullscreen变体 */

/* 分隔线 */
--xc-header-capsule-divider-width: 1px
--xc-header-capsule-divider-height: 16px
--xc-header-capsule-divider-color: rgba(0,0,0,0.1)      /* default变体 */
--xc-header-capsule-divider-color: rgba(255,255,255,0.3) /* fullscreen变体 */

胶囊按钮 (暗黑模式 - 需要 .dark 类)

css
/* 基础样式 */
--xc-header-dark-capsule-height: 32px
--xc-header-dark-capsule-bg: rgba(255,255,255,0.1)  /* default变体 */
--xc-header-dark-capsule-bg: rgba(255,255,255,0.2)  /* fullscreen变体 */
--xc-header-dark-capsule-border-width: 1px
--xc-header-dark-capsule-border-color: rgba(255,255,255,0.15) /* default变体 */
--xc-header-dark-capsule-border-color: rgba(255,255,255,0.3)  /* fullscreen变体 */
--xc-header-dark-capsule-radius: 16px
--xc-header-dark-capsule-blur: 10px

/* 按钮样式 */
--xc-header-dark-capsule-button-padding-x: 12px
--xc-header-dark-capsule-button-color: rgba(255,255,255,0.9) /* default变体 */
--xc-header-dark-capsule-button-color: #ffffff               /* fullscreen变体 */
--xc-header-dark-capsule-icon-size: 16px
--xc-header-dark-capsule-transition-duration: 200ms

/* 交互状态 */
--xc-header-dark-capsule-button-hover-bg: rgba(255,255,255,0.15) /* default变体 */
--xc-header-dark-capsule-button-hover-bg: rgba(255,255,255,0.1)  /* fullscreen变体 */
--xc-header-dark-capsule-button-active-bg: rgba(255,255,255,0.2) /* 两种变体相同 */

/* 分隔线 */
--xc-header-dark-capsule-divider-width: 1px
--xc-header-dark-capsule-divider-height: 16px
--xc-header-dark-capsule-divider-color: rgba(255,255,255,0.15) /* default变体 */
--xc-header-dark-capsule-divider-color: rgba(255,255,255,0.3)  /* fullscreen变体 */

布局说明

Default 变体

使用 Flexbox 三栏布局(左-中-右),不再使用绝对定位:

  • 左侧区域flex-shrink: 0(固定宽度)
  • 中间区域flex: 1(自适应,居中显示)
  • 右侧区域flex-shrink: 0(固定宽度)

这种布局方式避免了左右按钮与标题重叠的问题,内容会自动适应可用空间。

Fullscreen 变体

同样使用 Flexbox 三栏布局,并新增了中间标题区域支持。玻璃态按钮使用 backdrop-filter 实现毛玻璃效果。

设计理念

  1. 透明优先:两个变体默认都是透明背景,方便叠加在任何背景上
  2. Flexbox 布局:现代化的弹性布局,自动处理内容对齐和溢出
  3. CSS Token 驱动:所有样式都可通过 CSS 变量定制,无需修改组件源码
  4. 变体分离:Default 和 Fullscreen 有独立的样式体系,互不干扰

最佳实践

使用场景

  • Default 变体:适合常规页面、设置页面、列表页面等
  • Fullscreen 变体:适合相册、视频、地图等沉浸式全屏场景

自定义建议

  1. 主题定制:通过 CSS 变量定制,而非直接修改样式
  2. 背景设置:根据页面背景选择合适的文字和按钮颜色
  3. 按钮数量:右侧按钮建议不超过 3 个,避免布局拥挤

响应式

组件内置了响应式支持,在小屏设备(≤390px)上会自动调整字号。

基于 MIT 许可发布