跳到主要内容

Popover

  • 组件说明:点击触发的浮层容器,用于承载更复杂的操作内容、说明内容或自定义布局。
  • 组件组:Tips
  • 实现约定PopoverContent 保留 Radix 定位、Portal 与动画结构,design 层统一接管浮层卡片视觉。
  • 默认交互:默认将 children 作为 trigger 元素。
  • Figma 规范

基础用法

结果
Loading...
实时编辑器
render(
  <Popover content="Popover content">
    <Button variant="secondary" size="sm">
      Open Popover
    </Button>
  </Popover>,
)

位置变体

Popover 支持 8 个主要位置,通过 sidealign 组合控制。

结果
Loading...
实时编辑器
render(
  <div style={{ display: 'flex', flexDirection: 'column', gap: 24, padding: '48px 0' }}>
    <div style={{ display: 'flex', justifyContent: 'center', gap: 24 }}>
      {[
        { label: 'Top-Start', side: 'top', align: 'start' },
        { label: 'Top', side: 'top', align: 'center' },
        { label: 'Top-End', side: 'top', align: 'end' },
      ].map(({ label, side, align }) => (
        <Popover
          key={label}
          title={label}
          content="Popover content"
          side={side}
          align={align}
          defaultOpen
        >
          <Button variant="secondary" size="sm">
            {label}
          </Button>
        </Popover>
      ))}
    </div>

    <div style={{ display: 'flex', justifyContent: 'space-between', padding: '0 120px' }}>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 24 }}>
        {[
          { label: 'Left-Start', side: 'left', align: 'start' },
          { label: 'Left', side: 'left', align: 'center' },
          { label: 'Left-End', side: 'left', align: 'end' },
        ].map(({ label, side, align }) => (
          <Popover
            key={label}
            title={label}
            content="Popover content"
            side={side}
            align={align}
            defaultOpen
          >
            <Button variant="secondary" size="sm">
              {label}
            </Button>
          </Popover>
        ))}
      </div>

      <div style={{ display: 'flex', flexDirection: 'column', gap: 24 }}>
        {[
          { label: 'Right-Start', side: 'right', align: 'start' },
          { label: 'Right', side: 'right', align: 'center' },
          { label: 'Right-End', side: 'right', align: 'end' },
        ].map(({ label, side, align }) => (
          <Popover
            key={label}
            title={label}
            content="Popover content"
            side={side}
            align={align}
            defaultOpen
          >
            <Button variant="secondary" size="sm">
              {label}
            </Button>
          </Popover>
        ))}
      </div>
    </div>

    <div style={{ display: 'flex', justifyContent: 'center', gap: 24 }}>
      {[
        { label: 'Bottom-Start', side: 'bottom', align: 'start' },
        { label: 'Bottom', side: 'bottom', align: 'center' },
        { label: 'Bottom-End', side: 'bottom', align: 'end' },
      ].map(({ label, side, align }) => (
        <Popover
          key={label}
          title={label}
          content="Popover content"
          side={side}
          align={align}
          defaultOpen
        >
          <Button variant="secondary" size="sm">
            {label}
          </Button>
        </Popover>
      ))}
    </div>
  </div>,
)

标题与内容

结果
Loading...
实时编辑器
render(
  <Popover
    title="Popover Title"
    content="Popover 适合承载更复杂的交互内容,而不是只放一行提示文字。"
  >
    <Button variant="tertiary" size="sm">
      Open
    </Button>
  </Popover>,
)

自定义内容区域

结果
Loading...
实时编辑器
render(
  <Popover
    className="w-[320px]"
    content={
      <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
        <div style={{ fontWeight: 600 }}>Custom Content</div>
        <div style={{ fontSize: 14, lineHeight: 1.6 }}>
          业务可以直接传入自定义节点,内部仍然使用统一的 Popover 壳子。
        </div>
      </div>
    }
  >
    <Button variant="tertiary" size="sm">
      Open Custom
    </Button>
  </Popover>,
)

Popover Props

属性类型默认值说明
childrenReactNode触发元素。默认直接将 children 作为 trigger。
contentReactNode浮层内容
titleReactNode浮层标题
side'top' | 'bottom' | 'left' | 'right''bottom'弹出方向
align'start' | 'center' | 'end''center'对齐方式
sideOffsetnumber8与触发元素的间距 (px)
classNamestring自定义样式类
asChildbooleantrue是否将 children 作为触发器本体