弹出框

鼠标点击在某个组件时,弹出的气泡式的卡片浮层。可以对卡片上的元素进行操作。

导入

import {
  Popover,
  PopoverTrigger,
  PopoverContent,
  PopoverHeader,
  PopoverBody,
  PopoverFooter,
  PopoverArrow,
  PopoverCloseButton,
} from "@resolid/react-ui";
  • Popover: 为其子级提供上下文的包装器。
  • PopoverTrigger: 用于包装引用或触发元素。
  • PopoverContent: 弹出框内容的容器。
  • PopoverHeader: 弹出框的标题。
  • PopoverBody: 包含弹出框主要内容的包装器。
  • PopoverFooter: 弹出框的页脚。
  • PopoverArrow: 指向引用或触发元素的视觉箭头。
  • PopoverCloseButton: 关闭弹出框的按钮。

基础

<Popover placement={"bottom"}>
  <PopoverTrigger asChild>
    <Button>打开弹出框</Button>
  </PopoverTrigger>
  <PopoverContent className={"max-w-96"}>
    <PopoverCloseButton />
    <PopoverHeader>关于 Resolid Remix</PopoverHeader>
    <PopoverBody>使用 Remix 驱动的全栈网站,展示使用现代 Web 技术构建高性能、可扩展和用户友好的 Web 应用程序的最佳实践。</PopoverBody>
  </PopoverContent>
</Popover>
<Popover placement={"bottom"}>
  <PopoverTrigger asChild>
    <Button>打开带有箭头的弹出框</Button>
  </PopoverTrigger>
  <PopoverContent>
    <PopoverArrow />
    <PopoverBody>有箭头的弹出框内容</PopoverBody>
  </PopoverContent>
</Popover>

动画持续时间

<Popover duration={3000}>
  <PopoverTrigger asChild>
    <Button>动画持续时间</Button>
  </PopoverTrigger>
  <PopoverContent>
    <PopoverBody>持续时间很长</PopoverBody>
  </PopoverContent>
</Popover>

初始焦点

const focusRef = useRef();

return (
  <Popover initialFocus={focusRef} closeOnBlur={false}>
    {({ opened, close }) => (
      <>
        <PopoverTrigger asChild>
          <Button>{opened ? "关闭" : "打开"}弹出框</Button>
        </PopoverTrigger>
        <PopoverContent>
          <PopoverCloseButton />
          <PopoverHeader>表单弹出框</PopoverHeader>
          <form>
            <PopoverBody className={"flex flex-col gap-2"}>
              <div className={"flex items-center justify-between gap-5"}>
                <label htmlFor={"username"}>用户名</label>
                <Input ref={focusRef} id={"username"} />
              </div>
              <div className={"flex items-center justify-between gap-5"}>
                <label htmlFor={"email"}>电子邮件</label>
                <Input id={"email"} />
              </div>
            </PopoverBody>
            <PopoverFooter className={"flex flex-row justify-end gap-5"}>
              <Button variant={"soft"} color={"neutral"} onClick={close}>
                关闭
              </Button>
              <Button>确定</Button>
            </PopoverFooter>
          </form>
        </PopoverContent>
      </>
    )}
  </Popover>
);

访问内部状态

<Popover closeOnBlur={false}>
  {({ opened, close }) => (
    <>
      <PopoverTrigger asChild>
        <Button>{opened ? "关闭" : "打开"}弹出框</Button>
      </PopoverTrigger>
      <PopoverContent>
        <PopoverBody>弹出框内容</PopoverBody>
        <PopoverFooter className={"flex justify-center"}>
          <Button variant={"soft"} color={"neutral"} onClick={close}>
            关闭
          </Button>
        </PopoverFooter>
      </PopoverContent>
    </>
  )}
</Popover>

触发方式

<Popover trigger={'hover'}>
  <PopoverTrigger asChild>
    <Button>悬停触发</Button>
  </PopoverTrigger>
  <PopoverContent>
    <PopoverArrow />
    <PopoverBody>悬停弹出框</PopoverBody>
  </PopoverContent>
</Popover>

嵌套弹出框

  <Popover>
    <PopoverTrigger asChild>
      <Button>打开第一层</Button>
    </PopoverTrigger>
    <PopoverContent>
      <PopoverBody className={"flex flex-col gap-2"}>
        <p>第一层内容</p>
        <div className={"text-center"}>
          <Popover placement={"bottom"}>
            <PopoverTrigger asChild>
              <Button>打开第二层</Button>
            </PopoverTrigger>
            <PopoverContent>
              <PopoverBody>
                <p>第二层内容</p>
              </PopoverBody>
            </PopoverContent>
          </Popover>
        </div>
      </PopoverBody>
    </PopoverContent>
  </Popover>

放置位置

<div
  className={"mx-auto grid w-fit gap-2"}
  style={{
    gridTemplateAreas:
      '".           top-start     top         top-end       .            "' +
      '"left-start  .             .           .             right-start  "' +
      '"left        .             center      .             right        "' +
      '"left-end    .             .           .             right-end    "' +
      '".           bottom-start  bottom      bottom-end    .            "',
  }}
>
  {[
    ["top-start", "上左"],
    ["top", "上"],
    ["top-end", "上右"],
    ["left-start", "左上"],
    ["left", "左"],
    ["left-end", "左下"],
    ["auto", "自动"],
    ["right-start", "右上"],
    ["right", "右"],
    ["right-end", "右下"],
    ["bottom-start", "下左"],
    ["bottom", "下"],
    ["bottom-end", "下右"],
  ].map(([placement, name]) => (
    <Popover key={placement} placement={placement}>
      <PopoverTrigger asChild>
        <span
          style={{ gridArea: placement == "auto" ? "center" : placement }}
          className={
            "flex h-12 w-12 cursor-default items-center justify-center rounded bg-bg-muted text-center text-sm leading-tight"
          }
        >
          {name}
        </span>
      </PopoverTrigger>
      <PopoverContent>
        <PopoverArrow />
        <PopoverCloseButton />
        <PopoverHeader>弹出框头部</PopoverHeader>
        <PopoverBody>{name}位置弹出框</PopoverBody>
        <PopoverFooter>弹出框底部</PopoverFooter>
      </PopoverContent>
    </Popover>
  ))}
</div>

属性

属性trigger类型"click" | "hover"默认值'click'必须false
属性onClose类型() => void默认值-必须false
属性onCloseComplete类型() => void默认值-必须false
属性initialFocus类型number | RefObject<HTMLElement>默认值-必须false
属性modal类型boolean默认值true必须false
属性closeOnEsc类型boolean默认值true必须false
属性closeOnBlur类型boolean默认值true必须false
属性placement类型"auto" | Placement默认值'auto'必须false
属性duration类型number默认值'250'必须false