使用

Popover 基于 Floating UI 实现. 可以完全自定义弹出的内容.

Tooltip,Combobox等组件都是基于Popover实现

基本

默认点击target时打开.

鼠标覆盖时(hover)打开

键盘导航得到焦点(tab focus)时打开

显示箭头

PopoverwithArrow属性控制着是否显示箭头

withArrowtrue

  • Popoverposition属性设置为*-start*-end值时, 并且arrowPosition属性为side时, 箭头会被定位在目标元素的边, arrowOffset属性可以对其进行偏移.

  • 其它情况下, 箭头会被定位在目标元素的中心。arrowOffset属性会被忽略.

Arrow position:
Arrow size:
7
Arrow radius:
0
Arrow offset:
10

受控和非受控模式

opened为受控属性, defaultOpened为非受控属性. 不提供opened属性则在非受控模式下, 此时点击Target内孩子则会打开弹出框.
当提供了opened属性则在受控模式下, 此时不会自动打开弹出框, 必须使用手动设置受控属性值为true才会打开弹出框

import { Popover, Button } from "@rtdui/core";

export default function Demo() {
  const [open, setOpen] = React.useState(false);

  return (
    <Popover opened={open} onChange={setOpen}>
      <Popover.Target>
        <Button onClick={(e) => setOpen(true)}>popover</Button>
      </Popover.Target>
      <Popover.Dropdown>
        <div className="w-80 h-40 bg-base-200 p-8 rounded-box">abcdefg</div>
      </Popover.Dropdown>
    </Popover>
  );
}

焦点围栏

PopovertrapFocus属性控制是否启用焦点围栏, 默认为false.
焦点围栏是指当弹出框显示时, 键盘Tab键的焦点跳转范围限定在弹出框内. 对于弹出框中带有输入控件时尤其有用.

过渡效果

Popover支持Transition组件提供的预置过渡效果和自定义效果, 默认为"fade"

禁用

Popoverdisabled属性控制着是否禁止弹出.

Disabled

保持挂载

PopoverkeepMounted属性控制着弹出框关闭时是否保持挂载, 默认为false, 表示弹出框关闭时卸载组件. 如果为true,表示弹出框关闭时不卸载组件,但不可见.

Middlewares

Popover是基于Floating UI实现的, Popover支持的Floating UI中间件:

  • shift 中间件在主轴方向移位弹出框使其保持在视口中. 该中间件默认启用.
  • flip 中间件改变弹出框的定位位置使其保持在视口中. 该中间件默认启用
  • inline 中间件改进对内联元素的定位. 该中间件默认未启用.
  • size 中间件管理弹出框的尺寸. 默认当Popoverwidth属性为target自动启用, 否则未启用.

启用或禁用中间件:

import { Popover } from "@rtdui/core";

function Demo() {
  return (
    <Popover
      middlewares={{ flip: false, shift: { padding: 20 } }} // 禁用flip中间件, 设置shift中间件的自定义选项.
      position="bottom"
    >
      {/* Popover content */}
    </Popover>
  );
}

嵌套使用

嵌套Popover要求子Popover必须禁用withPortal属性. 如果子Portal没有被禁用, 点击子Popover外部会关闭嵌套的所有Popover

所有基于Combobox的组件(间接基于Popover), 如AutoComplete,Select,MultiSelect, TagsInput内部都使用了Popover, 以及直接基于Popover构建的组件, 如Tooltip组件, 这些组件用在Popover组件内, 必须设置它们的withPortal属性为false

import { Button, Popover, Select } from "@rtdui/core";

function Demo() {
  return (
    <Popover width={300} position="bottom" withArrow shadow="md">
      <Popover.Target>
        <Button>Toggle popover</Button>
      </Popover.Target>
      <Popover.Dropdown>
        <AutoComplete
          comboboxProps={{ withinPortal: false }} // 基于Combobox的通过comboboxProps.withinPortal禁用
          label="DatePickerInput within Popover"
          placeholder="DatePickerInput within Popover"
          data={["React", "Angular", "Svelte", "Vue"]}
        />
        <Select
          comboboxProps={{ withinPortal: false }} // 基于Combobox的通过comboboxProps.withinPortal禁用
          label="Select within Popover"
          placeholder="Select within Popover"
          data={["React", "Angular", "Svelte", "Vue"]}
        />
        <MultiSelect
          comboboxProps={{ withinPortal: false }} // 基于Combobox的通过comboboxProps.withinPortal禁用
          label="Select within Popover"
          placeholder="Select within Popover"
          data={["React", "Angular", "Svelte", "Vue"]}
        />
        <TagsInput
          comboboxProps={{ withinPortal: false }} // 基于Combobox的通过comboboxProps.withinPortal禁用
          label="Select within Popover"
          placeholder="Select within Popover"
          data={["React", "Angular", "Svelte", "Vue"]}
        />
        <Tooltip
          withinPortal={false} // 直接基于Popover的通过withinPortal禁用
          tip="click me"
        >
          <button></button>
        </Tooltip>
      </Popover.Dropdown>
    </Popover>
  );
}