跳至正文

Drawer

从屏幕边缘滑入的面板。

浏览器
Chrome 123+Firefox 121+Safari 17.5+
层级
0
压缩后大小
4.01 kB
强制布局预算
0 ms
axe 预算
0
支持 SSR
是
基于
elements/dialog
公开契约
测试环境

交互示例

Drawer

关闭

设置

调整工作区的偏好设置。

在较小屏幕上,此面板变为底部面板。从手柄处向下滑动、点击遮罩或使用“关闭”即可关闭。

吸附点

动态

拖动手柄以展开或关闭底部面板。

最近动态显示在这里。

宽度

SM抽屉

原生对话框控件在水合前即可使用。

在手机上,它会变为底部面板。

MD抽屉

原生对话框控件在水合前即可使用。

在手机上,它会变为底部面板。

LG抽屉

原生对话框控件在水合前即可使用。

在手机上,它会变为底部面板。

FULL抽屉

原生对话框控件在水合前即可使用。

在手机上,它会变为底部面板。

方向

工作区设置

调整工作区偏好设置。

工作区设置

调整工作区偏好设置。

工作区设置

调整工作区偏好设置。

工作区设置

调整工作区偏好设置。

import { DrawerPanel } from "@gunkin/uiify";

export default function Example() {
  return (
    <div className="">
      <DrawerPanel
        id="settings-drawer"
        side="right"
        trigger="Open settings"
        title="Settings"
        description="Adjust your preferences."
      />
    </div>
  );
}
@layer components {
  [data-uiify-drawer][data-part="content"] {
    --uiify-drawer-inline-size: 32rem;

    margin: 0;
    inline-size: 100%;
    max-inline-size: 100%;
    max-block-size: 100dvh;
    padding: var(--space-xl);
    border: var(--border-width) solid var(--border);
    background: var(--popover);
    color: var(--popover-foreground);
    box-shadow: var(--shadow-modal);
    flex-direction: column;
    gap: var(--space-md);
  }
  [data-uiify-drawer][data-part="content"][open] {
    display: flex;
  }
  [data-uiify-drawer][data-size="sm"] {
    --uiify-drawer-inline-size: 24rem;
  }
  [data-uiify-drawer][data-size="lg"] {
    --uiify-drawer-inline-size: 40rem;
  }
  [data-uiify-drawer][data-size="full"] {
    --uiify-drawer-inline-size: 100%;
  }
  [data-uiify-drawer][data-part="content"]::backdrop {
    background: rgb(0 0 0 / 45%);
  }
  [data-uiify-drawer][data-backdrop="transparent"]::backdrop {
    background: transparent;
  }
  [data-uiify-drawer][data-part="content"][data-side="bottom"] {
    margin-block-start: auto;
    block-size: min(var(--uiify-drawer-inline-size), 80dvh);
    max-block-size: 80dvh;
    border-start-start-radius: var(--radius-xl);
    border-start-end-radius: var(--radius-xl);
    transform: var(--uiify-drawer-transform, none);
  }
  [data-uiify-drawer][data-part="content"][data-side="top"] {
    margin-block-end: auto;
    block-size: min(var(--uiify-drawer-inline-size), 80dvh);
    max-block-size: 80dvh;
    border-end-start-radius: var(--radius-xl);
    border-end-end-radius: var(--radius-xl);
    transform: var(--uiify-drawer-transform, none);
  }
  [data-uiify-drawer][data-part="content"]:is([data-side="left"], [data-side="right"]) {
    inline-size: min(var(--uiify-drawer-inline-size), 100%);
    block-size: 100dvh;
    transform: var(--uiify-drawer-transform, none);
  }
  [data-uiify-drawer][data-part="content"][data-side="left"] {
    margin-inline-end: auto;
  }
  [data-uiify-drawer][data-part="content"][data-side="right"] {
    margin-inline-start: auto;
    border-start-end-radius: 0;
    border-end-end-radius: 0;
  }
  :dir(rtl) [data-uiify-drawer][data-part="content"][data-side="left"] {
    margin-inline: auto 0;
  }
  :dir(rtl) [data-uiify-drawer][data-part="content"][data-side="right"] {
    margin-inline: 0 auto;
  }
  [data-uiify-drawer][data-part="content"][data-size="full"] {
    inline-size: 100dvi;
    max-inline-size: 100dvi;
    block-size: 100dvh;
    max-block-size: 100dvh;
  }
  [data-uiify-drawer] [data-part="header"] {
    position: relative;
    flex: none;
    padding-inline-end: 2.75rem;
  }
  [data-uiify-drawer] [data-part="body"] {
    min-block-size: 0;
    overflow: auto;
    overscroll-behavior: contain;
    touch-action: pan-y;
  }
  [data-uiify-drawer] [data-part="footer"] {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: var(--space-sm);
  }
  [data-uiify-drawer] [data-part="close"] {
    display: inline-grid;
    place-items: center;
    inline-size: 2.25rem;
    block-size: 2.25rem;
    padding: 0;
    border: 0;
    border-radius: 50%;
    corner-shape: round;
    background: var(--secondary);
    color: var(--secondary-foreground);
  }
  [data-uiify-drawer] [data-part="header"] > [data-part="close"] {
    position: absolute;
    inset-block-start: 0;
    inset-inline-end: 0;
  }
  [data-uiify-drawer] :is([data-part="grabber"], [data-part="handle"]) {
    display: none;
    flex: none;
    block-size: 1.5rem;
    touch-action: none;
  }
  [data-uiify-drawer] :is([data-part="grabber"], [data-part="handle"])::after {
    content: "";
    display: block;
    inline-size: 2.25rem;
    block-size: 0.25rem;
    margin-block: 0.5rem 0;
    margin-inline: auto;
    border-radius: 999px;
    background: var(--border);
  }
  [data-uiify-drawer][data-snap-enabled] [data-part="handle"] {
    display: block;
  }

  @media (width < 40rem) {
    [data-uiify-drawer][data-part="content"][data-side] {
      inline-size: 100dvi;
      max-inline-size: 100dvi;
      block-size: auto;
      min-block-size: 50dvh;
      max-block-size: 80dvh;
      margin-block: auto 0;
      margin-inline: 0;
      border-start-start-radius: var(--radius-xl);
      border-start-end-radius: var(--radius-xl);
      border-end-start-radius: 0;
      border-end-end-radius: 0;
      transform: var(--uiify-drawer-transform, none);
      translate: 0 var(--uiify-sheet-offset, 0);
      padding-block-end: calc(var(--space-xl) + env(safe-area-inset-bottom));
    }
    [data-uiify-drawer][data-part="content"][data-size="full"] {
      block-size: 100dvh;
      max-block-size: 100dvh;
      border-radius: 0;
    }
    [data-uiify-drawer] :is([data-part="grabber"], [data-part="handle"]) {
      display: block;
    }
    [data-uiify-drawer] [data-part="header"] {
      touch-action: none;
    }
    [data-uiify-drawer][data-dragging] {
      transition: none;
    }
  }

  @media (prefers-reduced-motion: no-preference) {
    [data-uiify-drawer][data-part="content"] {
      transition:
        opacity 180ms ease,
        translate 220ms ease,
        transform 220ms ease,
        display 220ms allow-discrete,
        overlay 220ms allow-discrete;
    }
    [data-uiify-drawer][data-part="content"]:not([open]) {
      opacity: 0;
    }

    @starting-style {
      [data-uiify-drawer][data-part="content"][open] {
        opacity: 0;
      }
    }
  }
}
import { DrawerPanel } from "@gunkin/uiify";

export default function Example() {
  return (
    <div
      className={
        "[&[data-positioning=native]]:[--uiify-anchor-offset:var(--space-sm)] [&_[data-positioning=native]]:[--uiify" +
        "-anchor-offset:var(--space-sm)] [&[popover]:popover-open:not([data-positioning=native])]:[margin:revert] [&" +
        "_[popover]:popover-open:not([data-positioning=native])]:[margin:revert] [&_[data-uiify-drawer][data-part=tr" +
        "igger]]:relative [&_[data-uiify-drawer][data-part=trigger]]:inline-flex [&_[data-uiify-drawer][data-part=tr" +
        "igger]]:min-h-11 [&_[data-uiify-drawer][data-part=trigger]]:min-w-11 [&_[data-uiify-drawer][data-part=trigg" +
        "er]]:items-center [&_[data-uiify-drawer][data-part=trigger]]:justify-center [&_[data-uiify-drawer][data-par" +
        "t=trigger]]:rounded-full [&_[data-uiify-drawer][data-part=trigger]]:border-[length:var(--border-width)] [&_" +
        "[data-uiify-drawer][data-part=trigger]]:border-solid [&_[data-uiify-drawer][data-part=trigger]]:border-tran" +
        "sparent [&_[data-uiify-drawer][data-part=trigger]]:bg-foreground [&_[data-uiify-drawer][data-part=trigger]]" +
        ":px-5 [&_[data-uiify-drawer][data-part=trigger]]:py-0 [&_[data-uiify-drawer][data-part=trigger]]:text-backg" +
        "round [&_[data-uiify-drawer][data-part=trigger]]:text-base [&_[data-uiify-drawer][data-part=trigger]]:font-" +
        "medium [&_[data-uiify-drawer][data-part=trigger]]:leading-6 [&_[data-uiify-drawer][data-part=trigger]]:no-u" +
        "nderline [&_[data-uiify-drawer][data-part=trigger]]:cursor-pointer [&_[data-uiify-drawer][data-part=trigger" +
        "]]:[transition:var(--transition-colors)] [&_[data-uiify-drawer][data-part=content]]:[--uiify-drawer-inline-" +
        "size:32rem] [&_[data-uiify-drawer][data-size=sm][data-part=content]]:[--uiify-drawer-inline-size:24rem] [&_" +
        "[data-uiify-drawer][data-size=lg][data-part=content]]:[--uiify-drawer-inline-size:40rem] [&_[data-uiify-dra" +
        "wer][data-size=full][data-part=content]]:[--uiify-drawer-inline-size:100%] [&_[data-uiify-drawer][data-part" +
        "=content]]:m-0 [&_[data-uiify-drawer][data-part=content]]:w-full [&_[data-uiify-drawer][data-part=content]]" +
        ":max-w-full [&_[data-uiify-drawer][data-part=content]]:max-h-dvh [&_[data-uiify-drawer][data-part=content]]" +
        ":p-6 [&_[data-uiify-drawer][data-part=content]]:border [&_[data-uiify-drawer][data-part=content]]:border-bo" +
        "rder [&_[data-uiify-drawer][data-part=content]]:bg-popover [&_[data-uiify-drawer][data-part=content]]:text-" +
        "popover-foreground [&_[data-uiify-drawer][data-part=content]]:shadow-modal [&_[data-uiify-drawer][data-part" +
        "=content]]:flex-col [&_[data-uiify-drawer][data-part=content]]:gap-md [&_[data-uiify-drawer][data-part=cont" +
        "ent]]:rounded-xl [&_[data-uiify-drawer][data-part=content]]:[corner-shape:squircle] [&_[data-uiify-drawer][" +
        "data-part=content]::backdrop]:[background:rgb(0_0_0_/_45%)] [&_[data-uiify-drawer][data-part=content][data-" +
        "backdrop=transparent]::backdrop]:bg-transparent [&_[data-uiify-drawer][data-part=content][open]]:flex [&_[d" +
        "ata-uiify-drawer][data-part=content][data-side=right]]:ms-auto [&_[data-uiify-drawer][data-part=content][da" +
        "ta-side=left]]:me-auto [&_[data-uiify-drawer][data-part=content][data-side=top]]:mb-auto [&_[data-uiify-dra" +
        "wer][data-part=content][data-side=bottom]]:mt-auto [&_[data-uiify-drawer][data-part=content][data-side=bott" +
        "om]]:h-[min(var(--uiify-drawer-inline-size),_80dvh)] [&_[data-uiify-drawer][data-part=content][data-side=to" +
        "p]]:h-[min(var(--uiify-drawer-inline-size),_80dvh)] [&_[data-uiify-drawer][data-part=content][data-side=lef" +
        "t]]:w-[min(var(--uiify-drawer-inline-size),_100%)] [&_[data-uiify-drawer][data-part=content][data-side=righ" +
        "t]]:w-[min(var(--uiify-drawer-inline-size),_100%)] [&_[data-uiify-drawer][data-part=content]:is([data-side=" +
        "left],[data-side=right])]:[block-size:100dvh] [&_[data-uiify-drawer][data-part=content][data-side=right]]:[" +
        "border-start-end-radius:0] [&_[data-uiify-drawer][data-part=content][data-side=right]]:[border-end-end-radi" +
        "us:0] [&_[data-uiify-drawer][data-part=content][data-side=left]]:[border-start-start-radius:0] [&_[data-uii" +
        "fy-drawer][data-part=content][data-side=left]]:[border-end-start-radius:0] [&_[data-uiify-drawer][data-part" +
        "=content][data-size=full]]:[inline-size:100dvi] [&_[data-uiify-drawer][data-part=content][data-size=full]]:" +
        "[block-size:100dvh] [&_[data-uiify-drawer]_[data-part=header]]:relative [&_[data-uiify-drawer]_[data-part=h" +
        "eader]]:flex-none [&_[data-uiify-drawer]_[data-part=header]]:pe-11 [&_[data-uiify-drawer]_[data-part=body]]" +
        ":min-h-0 [&_[data-uiify-drawer]_[data-part=body]]:overflow-auto [&_[data-uiify-drawer]_[data-part=body]]:ov" +
        "erscroll-contain [&_[data-uiify-drawer]_[data-part=body]]:[touch-action:pan-y] [&_[data-uiify-drawer]_[data" +
        "-part=footer]]:flex [&_[data-uiify-drawer]_[data-part=footer]]:flex-wrap [&_[data-uiify-drawer]_[data-part=" +
        "footer]]:justify-end [&_[data-uiify-drawer]_[data-part=footer]]:gap-sm [&_[data-uiify-drawer]_[data-part=cl" +
        "ose]]:inline-grid [&_[data-uiify-drawer]_[data-part=close]]:place-items-center [&_[data-uiify-drawer]_[data" +
        "-part=close]]:size-9 [&_[data-uiify-drawer]_[data-part=close]]:p-0 [&_[data-uiify-drawer]_[data-part=close]" +
        "]:border-0 [&_[data-uiify-drawer]_[data-part=close]]:rounded-full [&_[data-uiify-drawer]_[data-part=close]]" +
        ":bg-secondary [&_[data-uiify-drawer]_[data-part=close]]:text-secondary-foreground [&_[data-uiify-drawer]_[d" +
        "ata-part=close]]:cursor-pointer [&_[data-uiify-drawer]_[data-part=header]>[data-part=close]]:absolute [&_[d" +
        "ata-uiify-drawer]_[data-part=header]>[data-part=close]]:[inset-block-start:0] [&_[data-uiify-drawer]_[data-" +
        "part=header]>[data-part=close]]:[inset-inline-end:0] [&_[data-uiify-drawer]_:is([data-part=grabber],[data-p" +
        "art=handle])]:hidden [&_[data-uiify-drawer]_:is([data-part=grabber],[data-part=handle])]:flex-none [&_[data" +
        "-uiify-drawer]_:is([data-part=grabber],[data-part=handle])]:[block-size:1.5rem] [&_[data-uiify-drawer]_:is(" +
        "[data-part=grabber],[data-part=handle])]:[touch-action:none] [&_[data-uiify-drawer]_:is([data-part=grabber]" +
        ",[data-part=handle])]:after:content-[''] [&_[data-uiify-drawer]_:is([data-part=grabber],[data-part=handle])" +
        "]:after:block [&_[data-uiify-drawer]_:is([data-part=grabber],[data-part=handle])]:after:w-9 [&_[data-uiify-" +
        "drawer]_:is([data-part=grabber],[data-part=handle])]:after:h-1 [&_[data-uiify-drawer]_:is([data-part=grabbe" +
        "r],[data-part=handle])]:after:[margin-block:0.5rem_0] [&_[data-uiify-drawer]_:is([data-part=grabber],[data-" +
        "part=handle])]:after:mx-auto [&_[data-uiify-drawer]_:is([data-part=grabber],[data-part=handle])]:after:roun" +
        "ded-full [&_[data-uiify-drawer]_:is([data-part=grabber],[data-part=handle])]:after:bg-border max-[40rem]:[&" +
        "_[data-uiify-drawer][data-part=content][data-side]]:[inline-size:100dvi] max-[40rem]:[&_[data-uiify-drawer]" +
        "[data-part=content][data-side]]:[block-size:auto] max-[40rem]:[&_[data-uiify-drawer][data-part=content][dat" +
        "a-side]]:[min-block-size:50dvh] max-[40rem]:[&_[data-uiify-drawer][data-part=content][data-side]]:[max-bloc" +
        "k-size:80dvh] max-[40rem]:[&_[data-uiify-drawer][data-part=content][data-side]]:[margin-block:auto_0] max-[" +
        "40rem]:[&_[data-uiify-drawer][data-part=content][data-side]]:[margin-inline:0] max-[40rem]:[&_[data-uiify-d" +
        "rawer][data-part=content][data-side]]:[border-start-start-radius:var(--radius-xl)] max-[40rem]:[&_[data-uii" +
        "fy-drawer][data-part=content][data-side]]:[border-start-end-radius:var(--radius-xl)] max-[40rem]:[&_[data-u" +
        "iify-drawer][data-part=content][data-side]]:[border-end-start-radius:0] max-[40rem]:[&_[data-uiify-drawer][" +
        "data-part=content][data-side]]:[border-end-end-radius:0] max-[40rem]:[&_[data-uiify-drawer][data-part=conte" +
        "nt][data-side]]:[padding-block-end:calc(var(--space-xl)_+_env(safe-area-inset-bottom))] max-[40rem]:[&_[dat" +
        "a-uiify-drawer]_:is([data-part=grabber],[data-part=handle])]:block max-[40rem]:[&_[data-uiify-drawer]_[data" +
        "-part=header]]:[touch-action:none] [&_[data-uiify-drawer][data-part=title]]:m-0 [&_[data-uiify-drawer][data" +
        "-part=title]]:text-[length:var(--text-xl)] [&_[data-uiify-drawer][data-part=description]]:m-0 [&_[data-uiif" +
        "y-drawer][data-part=description]]:text-muted-foreground [&_[data-uiify-drawer][data-part=description]]:text" +
        "-sm [&_[data-uiify-drawer][data-part=handle]]:mx-auto [&_[data-uiify-drawer][data-part=handle]]:h-1 [&_[dat" +
        "a-uiify-drawer][data-part=handle]]:w-10 [&_[data-uiify-drawer][data-part=handle]]:rounded-full [&_[data-uii" +
        "fy-drawer][data-part=handle]]:bg-muted-foreground"
      }
    >
      <DrawerPanel
        id="settings-drawer"
        side="right"
        trigger="Open settings"
        title="Settings"
        description="Adjust your preferences."
      />
    </div>
  );
}
/* app.css */

@layer reset, ui, app, tokens, base, demo, components, utilities, theme;

@import "@gunkin/uiify/styles/reset";

@import "@gunkin/uiify/components/behavior.css";

@import "@gunkin/uiify/styles/tokens";

@import "@gunkin/uiify/styles/tailwind";

@import "tailwindcss/utilities.css";

@theme { --spacing: 0.25rem; --font-weight-normal: 400; --font-weight-medium: 500; --font-weight-semibold: 600; --font-weight-bold: 700; }

@source inline('[&[data-positioning=native]]:[--uiify-anchor-offset:var(--space-sm)] [&_[data-positioning=native]]:[--uiify-anchor-offset:var(--space-sm)] [&[popover]:popover-open:not([data-positioning=native])]:[margin:revert] [&_[popover]:popover-open:not([data-positioning=native])]:[margin:revert] [&_[data-uiify-drawer][data-part=trigger]]:relative [&_[data-uiify-drawer][data-part=trigger]]:inline-flex [&_[data-uiify-drawer][data-part=trigger]]:min-h-11 [&_[data-uiify-drawer][data-part=trigger]]:min-w-11 [&_[data-uiify-drawer][data-part=trigger]]:items-center [&_[data-uiify-drawer][data-part=trigger]]:justify-center [&_[data-uiify-drawer][data-part=trigger]]:rounded-full [&_[data-uiify-drawer][data-part=trigger]]:border-[length:var(--border-width)] [&_[data-uiify-drawer][data-part=trigger]]:border-solid [&_[data-uiify-drawer][data-part=trigger]]:border-transparent [&_[data-uiify-drawer][data-part=trigger]]:bg-foreground [&_[data-uiify-drawer][data-part=trigger]]:px-5 [&_[data-uiify-drawer][data-part=trigger]]:py-0 [&_[data-uiify-drawer][data-part=trigger]]:text-background [&_[data-uiify-drawer][data-part=trigger]]:text-base [&_[data-uiify-drawer][data-part=trigger]]:font-medium [&_[data-uiify-drawer][data-part=trigger]]:leading-6 [&_[data-uiify-drawer][data-part=trigger]]:no-underline [&_[data-uiify-drawer][data-part=trigger]]:cursor-pointer [&_[data-uiify-drawer][data-part=trigger]]:[transition:var(--transition-colors)] [&_[data-uiify-drawer][data-part=content]]:[--uiify-drawer-inline-size:32rem] [&_[data-uiify-drawer][data-size=sm][data-part=content]]:[--uiify-drawer-inline-size:24rem] [&_[data-uiify-drawer][data-size=lg][data-part=content]]:[--uiify-drawer-inline-size:40rem] [&_[data-uiify-drawer][data-size=full][data-part=content]]:[--uiify-drawer-inline-size:100%] [&_[data-uiify-drawer][data-part=content]]:m-0 [&_[data-uiify-drawer][data-part=content]]:w-full [&_[data-uiify-drawer][data-part=content]]:max-w-full [&_[data-uiify-drawer][data-part=content]]:max-h-dvh [&_[data-uiify-drawer][data-part=content]]:p-6 [&_[data-uiify-drawer][data-part=content]]:border [&_[data-uiify-drawer][data-part=content]]:border-border [&_[data-uiify-drawer][data-part=content]]:bg-popover [&_[data-uiify-drawer][data-part=content]]:text-popover-foreground [&_[data-uiify-drawer][data-part=content]]:shadow-modal [&_[data-uiify-drawer][data-part=content]]:flex-col [&_[data-uiify-drawer][data-part=content]]:gap-md [&_[data-uiify-drawer][data-part=content]]:rounded-xl [&_[data-uiify-drawer][data-part=content]]:[corner-shape:squircle] [&_[data-uiify-drawer][data-part=content]::backdrop]:[background:rgb(0_0_0_/_45%)] [&_[data-uiify-drawer][data-part=content][data-backdrop=transparent]::backdrop]:bg-transparent [&_[data-uiify-drawer][data-part=content][open]]:flex [&_[data-uiify-drawer][data-part=content][data-side=right]]:ms-auto [&_[data-uiify-drawer][data-part=content][data-side=left]]:me-auto [&_[data-uiify-drawer][data-part=content][data-side=top]]:mb-auto [&_[data-uiify-drawer][data-part=content][data-side=bottom]]:mt-auto [&_[data-uiify-drawer][data-part=content][data-side=bottom]]:h-[min(var(--uiify-drawer-inline-size),_80dvh)] [&_[data-uiify-drawer][data-part=content][data-side=top]]:h-[min(var(--uiify-drawer-inline-size),_80dvh)] [&_[data-uiify-drawer][data-part=content][data-side=left]]:w-[min(var(--uiify-drawer-inline-size),_100%)] [&_[data-uiify-drawer][data-part=content][data-side=right]]:w-[min(var(--uiify-drawer-inline-size),_100%)] [&_[data-uiify-drawer][data-part=content]:is([data-side=left],[data-side=right])]:[block-size:100dvh] [&_[data-uiify-drawer][data-part=content][data-side=right]]:[border-start-end-radius:0] [&_[data-uiify-drawer][data-part=content][data-side=right]]:[border-end-end-radius:0] [&_[data-uiify-drawer][data-part=content][data-side=left]]:[border-start-start-radius:0] [&_[data-uiify-drawer][data-part=content][data-side=left]]:[border-end-start-radius:0] [&_[data-uiify-drawer][data-part=content][data-size=full]]:[inline-size:100dvi] [&_[data-uiify-drawer][data-part=content][data-size=full]]:[block-size:100dvh] [&_[data-uiify-drawer]_[data-part=header]]:relative [&_[data-uiify-drawer]_[data-part=header]]:flex-none [&_[data-uiify-drawer]_[data-part=header]]:pe-11 [&_[data-uiify-drawer]_[data-part=body]]:min-h-0 [&_[data-uiify-drawer]_[data-part=body]]:overflow-auto [&_[data-uiify-drawer]_[data-part=body]]:overscroll-contain [&_[data-uiify-drawer]_[data-part=body]]:[touch-action:pan-y] [&_[data-uiify-drawer]_[data-part=footer]]:flex [&_[data-uiify-drawer]_[data-part=footer]]:flex-wrap [&_[data-uiify-drawer]_[data-part=footer]]:justify-end [&_[data-uiify-drawer]_[data-part=footer]]:gap-sm [&_[data-uiify-drawer]_[data-part=close]]:inline-grid [&_[data-uiify-drawer]_[data-part=close]]:place-items-center [&_[data-uiify-drawer]_[data-part=close]]:size-9 [&_[data-uiify-drawer]_[data-part=close]]:p-0 [&_[data-uiify-drawer]_[data-part=close]]:border-0 [&_[data-uiify-drawer]_[data-part=close]]:rounded-full [&_[data-uiify-drawer]_[data-part=close]]:bg-secondary [&_[data-uiify-drawer]_[data-part=close]]:text-secondary-foreground [&_[data-uiify-drawer]_[data-part=close]]:cursor-pointer [&_[data-uiify-drawer]_[data-part=header]>[data-part=close]]:absolute [&_[data-uiify-drawer]_[data-part=header]>[data-part=close]]:[inset-block-start:0] [&_[data-uiify-drawer]_[data-part=header]>[data-part=close]]:[inset-inline-end:0] [&_[data-uiify-drawer]_:is([data-part=grabber],[data-part=handle])]:hidden [&_[data-uiify-drawer]_:is([data-part=grabber],[data-part=handle])]:flex-none [&_[data-uiify-drawer]_:is([data-part=grabber],[data-part=handle])]:[block-size:1.5rem] [&_[data-uiify-drawer]_:is([data-part=grabber],[data-part=handle])]:[touch-action:none] [&_[data-uiify-drawer]_:is([data-part=grabber],[data-part=handle])]:after:block [&_[data-uiify-drawer]_:is([data-part=grabber],[data-part=handle])]:after:w-9 [&_[data-uiify-drawer]_:is([data-part=grabber],[data-part=handle])]:after:h-1 [&_[data-uiify-drawer]_:is([data-part=grabber],[data-part=handle])]:after:[margin-block:0.5rem_0] [&_[data-uiify-drawer]_:is([data-part=grabber],[data-part=handle])]:after:mx-auto [&_[data-uiify-drawer]_:is([data-part=grabber],[data-part=handle])]:after:rounded-full [&_[data-uiify-drawer]_:is([data-part=grabber],[data-part=handle])]:after:bg-border max-[40rem]:[&_[data-uiify-drawer][data-part=content][data-side]]:[inline-size:100dvi] max-[40rem]:[&_[data-uiify-drawer][data-part=content][data-side]]:[block-size:auto] max-[40rem]:[&_[data-uiify-drawer][data-part=content][data-side]]:[min-block-size:50dvh] max-[40rem]:[&_[data-uiify-drawer][data-part=content][data-side]]:[max-block-size:80dvh] max-[40rem]:[&_[data-uiify-drawer][data-part=content][data-side]]:[margin-block:auto_0] max-[40rem]:[&_[data-uiify-drawer][data-part=content][data-side]]:[margin-inline:0] max-[40rem]:[&_[data-uiify-drawer][data-part=content][data-side]]:[border-start-start-radius:var(--radius-xl)] max-[40rem]:[&_[data-uiify-drawer][data-part=content][data-side]]:[border-start-end-radius:var(--radius-xl)] max-[40rem]:[&_[data-uiify-drawer][data-part=content][data-side]]:[border-end-start-radius:0] max-[40rem]:[&_[data-uiify-drawer][data-part=content][data-side]]:[border-end-end-radius:0] max-[40rem]:[&_[data-uiify-drawer][data-part=content][data-side]]:[padding-block-end:calc(var(--space-xl)_+_env(safe-area-inset-bottom))] max-[40rem]:[&_[data-uiify-drawer]_:is([data-part=grabber],[data-part=handle])]:block max-[40rem]:[&_[data-uiify-drawer]_[data-part=header]]:[touch-action:none] [&_[data-uiify-drawer][data-part=title]]:m-0 [&_[data-uiify-drawer][data-part=title]]:text-[length:var(--text-xl)] [&_[data-uiify-drawer][data-part=description]]:m-0 [&_[data-uiify-drawer][data-part=description]]:text-muted-foreground [&_[data-uiify-drawer][data-part=description]]:text-sm [&_[data-uiify-drawer][data-part=handle]]:mx-auto [&_[data-uiify-drawer][data-part=handle]]:h-1 [&_[data-uiify-drawer][data-part=handle]]:w-10 [&_[data-uiify-drawer][data-part=handle]]:rounded-full [&_[data-uiify-drawer][data-part=handle]]:bg-muted-foreground');

@source inline("[&_[data-uiify-drawer]_:is([data-part=grabber],[data-part=handle])]:after:content-['']");

@layer base { :root { --uiify-control-text: var(--text-sm); } @media (pointer: coarse) { :root { --uiify-control-text: var(--text-base); } } }

/* Authored animation and registered properties used by the Tailwind skin.
 * Visual rules belong in utility recipes; only at-rule definitions live here. */
@layer components {
  @keyframes uiify-presence-in {
    from {
      opacity: 0;
      scale: var(--presence-scale);
    }
  }
}

@layer components {
  @keyframes uiify-presence-out {
    to {
      opacity: 0;
      scale: var(--presence-scale);
    }
  }
}

@property --uiify-spinner-tail {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}

@property --uiify-spinner-length {
  syntax: "<angle>";
  inherits: false;
  initial-value: 36deg;
}

@layer components {
  @keyframes uiify-spinner-rotate {
    to {
      transform: rotate(360deg);
    }
  }
}

@layer components {
  @keyframes uiify-spinner-orbit {
    0% {
      --uiify-spinner-tail: 0deg;
      --uiify-spinner-length: 36deg;
    }

    50% {
      --uiify-spinner-tail: 90deg;
      --uiify-spinner-length: 324deg;
    }

    100% {
      --uiify-spinner-tail: 360deg;
      --uiify-spinner-length: 36deg;
    }
  }
}

@layer components {
  @keyframes uiify-skeleton-pulse {
    50% {
      opacity: 0.45;
    }
  }
}

@layer components {
  @keyframes uiify-skeleton-shimmer {
    to {
      background-position: -200% 0;
    }
  }
}

@layer components {
  @keyframes uiify-skeleton-reveal {
    from {
      opacity: 0;
    }
    to {
      opacity: 1;
    }
  }
}

@property --candle-body-height {
  syntax: "<percentage>";
  inherits: true;
  initial-value: 0%;
}

@property --candle-body-top {
  syntax: "<percentage>";
  inherits: true;
  initial-value: 50%;
}

@property --candle-slot {
  syntax: "<percentage>";
  inherits: true;
  initial-value: 100%;
}

@property --candle-wick-height {
  syntax: "<percentage>";
  inherits: true;
  initial-value: 0%;
}

@property --candle-wick-top {
  syntax: "<percentage>";
  inherits: true;
  initial-value: 50%;
}

@property --candle-x {
  syntax: "<percentage>";
  inherits: true;
  initial-value: 0%;
}

@property --candle-scale {
  syntax: "<number>";
  inherits: true;
  initial-value: 1;
}

@property --line-y {
  syntax: "<percentage>";
  inherits: true;
  initial-value: 50%;
}

@property --line-prev-y {
  syntax: "<percentage>";
  inherits: true;
  initial-value: 50%;
}

@property --line-count {
  syntax: "<integer>";
  inherits: false;
  initial-value: 1;
}

@property --line-scale {
  syntax: "<number>";
  inherits: true;
  initial-value: 1;
}

@layer components {
  @keyframes uiify-otp-input-caret-blink {
    50% {
      opacity: 0;
    }
  }
}

API

DrawerPanel

属性类型默认值说明
size"sm" | "md" | "lg" | "full""md"桌面宽度:24rem、32rem、40rem或可用宽度。在移动端,所有尺寸都变为纵向底部面板。
dismiss"any" | "closerequest" | "none""any"原生关闭策略。Any允许点击遮罩、Escape和移动端向下滑动;none要求显式关闭控件。
backdrop"opaque" | "transparent""opaque"遮罩外观;不改变模态语义。
id*string—触发器和关闭按钮指向的唯一对话框id,让抽屉在水合前即可打开和关闭。
trigger*ReactNode—打开抽屉的按钮内容。
title*ReactNode—在抽屉内渲染的标题,用作无障碍名称。
descriptionReactNode—在标题下方渲染的辅助文本,由aria-describedby引用。
childrenReactNode—位于描述和关闭按钮之间的主体内容。
side"top" | "right" | "bottom" | "left""bottom"抽屉从哪条边缘滑入。
closeLabelstring"Close"圆形关闭图标的无障碍标签。
classNamestring—应用于dialog元素的类名。

Drawer.Root (client)

属性类型默认值说明
openboolean—受控打开状态。
defaultOpenboolean—非受控的初始打开状态。
onOpenChangeDialogChangeHandler—使用下一个打开状态及变更原因详情调用。
side"top" | "right" | "bottom" | "left""bottom"抽屉从哪条边缘滑入,同时决定拖动轴。
modalbooleantrue通过showModal()打开,使页面其余部分在遮罩后处于inert状态。
dismissiblebooleantrue允许拖过最后一个吸附点来关闭抽屉。
snapPointsreadonly number[]—拖动后面板停靠的位置,以抽屉尺寸的比例表示。
activeSnapPointnumber—受控吸附点,为snapPoints中的一个值。
defaultActiveSnapPointnumber—非受控的初始吸附点。
onSnapChange(snap: number) => void—使用抽屉最终停靠的吸附点调用。
childrenReactNode—Trigger、Content和内部组成部分。

Drawer.Trigger (client)

属性类型默认值说明
classNamestring—应用于触发器按钮的类名。
onClick(event: MouseEvent<HTMLButtonElement>) => void—点击触发器后、抽屉打开前调用。
refRef<HTMLButtonElement>—触发器按钮的ref,抽屉关闭时会重新聚焦该按钮。
childrenReactNode—触发器按钮的内容。

Drawer.Content (client)

属性类型默认值说明
classNamestring—应用于dialog元素的类名。
styleCSSProperties—与抽屉应用的拖动transform合并的内联style。
onCancelReactEventHandler<HTMLDialogElement>—原生dialog cancel事件发生时调用,例如按下Escape。
onCloseReactEventHandler<HTMLDialogElement>—原生dialog close事件发生时调用。
refRef<HTMLDialogElement>—dialog元素的ref。
childrenReactNode—抽屉内容。

Drawer.Title (client)

属性类型默认值说明
classNamestring—应用于标题元素的类名。
childrenReactNode—标题内容,成为抽屉的无障碍名称。

Drawer.Description (client)

属性类型默认值说明
classNamestring—应用于描述元素的类名。
childrenReactNode—描述内容,由aria-describedby引用。

Drawer.Close (client)

属性类型默认值说明
classNamestring—应用于关闭按钮的类名。
onClick(event: MouseEvent<HTMLButtonElement>) => void—点击关闭按钮后、抽屉关闭前调用。
childrenReactNode—关闭按钮的内容。

Drawer.Handle (client)

属性类型默认值说明
classNamestring—应用于拖动手柄的类名。
onPointerDown(event: PointerEvent<HTMLDivElement>) => void—在手柄上开始拖动时调用。
onPointerMove(event: PointerEvent<HTMLDivElement>) => void—拖动期间指针移动时调用。
onPointerUp(event: PointerEvent<HTMLDivElement>) => void—拖动结束且抽屉停靠到吸附点时调用。
onPointerCancel(event: PointerEvent<HTMLDivElement>) => void—浏览器取消拖动时调用。

键盘

按键操作
Enter / Space通过触发器打开对话框,或激活Close
Escape请求关闭,除非dismiss为none
Tab / Shift+Tab在模态对话框内移动

无障碍

DrawerPanel使用带目标id的对话框,因此打开、关闭、焦点限制和焦点返回在水合前就能工作;dismiss控制遮罩和Escape行为。面板有sm、md、lg和full宽度,在手机上变为底部面板。滑动从手柄或页头开始,因此主体仍可滚动。客户端API添加受控状态和吸附点。

样式钩子

data-uiify-drawerdata-partdata-sidedata-sizedata-backdropdata-statedata-dragging--uiify-drawer-inline-size--uiify-drawer-transform--uiify-sheet-offset
本页由机器翻译,尚未经人工审核。