@atlaskit/top-layer

中文文档
7.1.5发布于 2026/11/06Apache-2.0TypeScriptESM + CJS近 30 天下载 44.2万

基于 popover 和对话框的低层分层原始

中文使用文档
文档目录10 节
  1. 过量
  2. 对话框
  3. 页面表面
  4. 动画
  5. 流行动画
  6. 对话框动画
  7. 逐步加强
  8. 无障碍
  9. 已知的限制
  10. 文档

@atlaskit/上层

使用土生土长的低层顶层原始人 过量API (单位:千美元)popover="auto"和 <dialog> 键.

首先使用一个设计系统组件,例如弹出,Modal对话框,Toltip或Drop down菜单. 使用 只有在没有设计系统组件适合时,这些原始物才符合 platform-dst-top-layer 特性旗。 不使用本地语言 popover 或者说 <dialog> 直接元素: @atlaskit/design-system/no-native-popover-or-dialog ESLINT规则阻断它.

过量

初级原始:a <div> 与 popover 属性,加上一个小生命周期(动画, 基于角色的焦点管理,轻而易举地,巢被聚焦地恢复. 没错 没有 已经知道 放置或大小——用 useAnchoredPopover 需要锁定时钩子 内容.

import { useRef, useState } from 'react';
import { getAriaForTrigger } from '@atlaskit/top-layer/get-aria-for-trigger';
import { Popover } from '@atlaskit/top-layer/popover/popover';
import { PopoverSurface } from '@atlaskit/top-layer/popover-surface';
import { usePopoverId } from '@atlaskit/top-layer/use-popover-id';
import { useAnchoredPopover } from '@atlaskit/top-layer/use-anchored-popover';

function MyPopup() {
    const [isOpen, setIsOpen] = useState(false);
    const triggerRef = useRef<HTMLButtonElement>(null);
    const popoverRef = useRef<HTMLDivElement>(null);
    const popoverId = usePopoverId();

    useAnchoredPopover({
        anchorRef: triggerRef,
        popoverRef,
        placement: { axis: 'block', edge: 'end', align: 'start' },
        isOpen,
    });

    return (
        <>
            <button
                ref={triggerRef}
                onClick={() => setIsOpen((value) => !value)}
                {...getAriaForTrigger({ role: 'dialog', isOpen, popoverId })}
            >
                Open
            </button>
            <Popover
                ref={popoverRef}
                id={popoverId}
                role="dialog"
                label="Settings"
                isOpen={isOpen}
                shouldAnimate
                onClose={() => setIsOpen(false)}
            >
                <PopoverSurface>Content here</PopoverSurface>
            </Popover>
        </>
    );
}
  • 焦点修复是自动的. 浏览器为最外侧的弹出器处理; Popover 快照 document.activeElement 打开并恢复它 关闭为巢穴病例.
  • 对于默认覆盖样式(背景、阴影、边框-辐射),将内容包入 PopoverSurface 从 @atlaskit/top-layer/popover-surface。 。 。 .
  • 对于无触发或自定义定位的UI(旗帜、工具提示、反应-选择菜单门户),使用 Popover 独自一人,没有 useAnchoredPopover,或通过 isEnabled: false 关闭定位.
  • useAnchoredPopover 也拥有主锚关系测距 inlineSize 编号 : blockSize (单位:千美元)'content' | 'match-anchor' | 'min-anchor' | 'max-available',两个默认 'content'A级 风景帽写在两根轴上 无论你通过什么, 只能用最小的插轴 给它 A 'content' 内线轴是内容的自然宽度,所以对于空间来说,弹出器太宽 在锚上滑到更宽敞的一面而不是包裹; shouldPreserveInlineSize 选择 一个您拥有的元素, 并且已经从这个字符中样式化 。 见钩子的JSDoc和 notes/decisions/fit-available-space.md。 。 。 .

对话框

本地模式对话框 <dialog> 键. isOpen 电话 showModal() 财务报告和审定财务报表 close()它已经 没有视觉观点(没有宽度、表面或布局); 消费者如 @atlaskit/modal-dialog 添加 他们自己的。 A 类 label 或者说 labelledBy 需要时间.

import { Dialog } from '@atlaskit/top-layer/dialog-content';

<Dialog isOpen={isOpen} onClose={() => setIsOpen(false)} labelledBy={titleId}>
    <h2 id={titleId}>Heading</h2>
    Content
</Dialog>;
  • onClose({ reason }) 在允许的逃逸后起火( E)'escape')或单击背景 (单位:千美元)'overlay-click') (中文(简体) ). 设定 isOpen={false} 作为回应.
  • dismissedBy 限制用户解职 : 'escape-and-outside-click' (违约), 'escape' 或者说 'none'。只允许背景点击,使用默认并忽略 onClose 电话 reason: 'escape'。 。 。 .
  • 这个 <dialog> 已经 closedby="none"数字 : Dialog 处理 Escape 和 背景单击自己。 其它 关闭请求( 例如 Android back) 不关闭对话框, 不调用 onClose。 。 。 .

页面表面

页面表面使用费:不在上层的表面(例如侧面板,a) 网格或侧向导航),必须同上层平面并用. 他们取代 @atlaskit/layering 打开层观察者.

import { hasOpenDialogOrPopover } from '@atlaskit/top-layer/page-surface/has-open-dialog-or-popover';
import { requestClosePopovers } from '@atlaskit/top-layer/page-surface/request-close-popovers';
import { useCloseOnUnclaimedEscape } from '@atlaskit/top-layer/page-surface/use-close-on-unclaimed-escape';

// A side panel that closes on Escape, unless an open dialog or popover claimed it.
useCloseOnUnclaimedEscape({ isEnabled: isOpen, onClose: () => setIsOpen(false) });

// A grid that ignores keys while a dialog or popover opened from it is open.
if (hasOpenDialogOrPopover({ within: event.currentTarget })) {
    return;
}
  • useCloseOnUnclaimedEscape({ isEnabled, onClose, shouldClose, targetRef }) 关闭页面表面 (一个不在上层,例如侧面板) 关于 Escape. 浏览器关闭 在 Escape 本身的上层表面,但一页表面也接收到 Escape. 钩子 忽略声称的逃逸: 当 event.defaultPrevented 实值 true,当 event.repeat 实值 true, (中文(简体) ), 当另一个逃逸的主人在地表上方时(在逃逸时关闭的开阔地层,或标记) 页面表面; 参见 逃逸堆栈 notes/decisions/manual-light-dismiss-escape-stacking.md, (中文(简体) ), 或何时 shouldClose 返回时 false。通过 surfaceRef 来命名表层元素:一层 周围是它的下方。 它听着 document,或打开 targetRef 当你经过一个的时候 而焦点就在其中。 这个 targetRef 元素必须在 isEnabled 变成 true。不要将钩子用于 Popover 或一个 Dialog: 他们已经关闭了 Escape.
  • hasOpenDialogOrPopover({ within, type }) 返回时 true 当打开时 <dialog>,或打开 Popover 有个 onClose内 within (默认 : document) (中文(简体) ). 工具提示和弹出器 无 onClose 从不计数. type: 'modal' 只计算模式对话框。 活动时称: a keydown 听者仍然看到一个弹出器,同样的"逃出"会关闭.
  • requestClosePopovers({ within }) 电话 onClose({ reason: 'programmatic' }) 每个打开 内部可杂碎的弹出器 within它从不隐藏任何东西,也不要求对话。 使用 当布局发生变化时,例如边导航崩溃时.
  • 顶层表面使内出水 所以从元素内部打开的表面是DOM后人 这一点。 使用 within 在那里,你使用 观察员命名空间.

动画

两者 Popover 财务报告和审定财务报表 Dialog 支持基于CSS的出入口动画通过 shouldAnimate 道具 (英语). 动画使用 @starting-style 用于进入和进入 allow-discrete 打开 display编号 :overlay 用于退出——不需要JavaScript动画协调.

流行动画

过 shouldAnimate 启用默认弹出式出入口动画 :

import { Popover } from '@atlaskit/top-layer/popover/popover';

<Popover shouldAnimate role="dialog" label="My popover" isOpen={isOpen} onClose={onClose}>
    Content
</Popover>;

覆盖样式(背景、阴影、边框-光圈),将儿童包裹在 PopoverSurface 从 @atlaskit/top-layer/popover-surface。 。 。 .

使用 enteringAnimationXcss 财务报告和审定财务报表 exitingAnimationXcss 当构成的组件需要覆盖时 相位特定动画样式.

对话框动画

过 shouldAnimate 启用默认对话框的出入口动画 :

import { Dialog } from '@atlaskit/top-layer/dialog-content';

<Dialog shouldAnimate isOpen={isOpen} onClose={onClose} label="My dialog">
    Content
</Dialog>;

使用 enteringAnimationXcss 财务报告和审定财务报表 exitingAnimationXcss 当构成的组件需要覆盖时 相位特定动画样式.

逐步加强

没有浏览器 @starting-style 支持将立即显示/隐藏元素——没有断裂状态。 这个 prefers-reduced-motion: reduce 媒体查询设置所有过渡期间到 0s。 。 。 .

无障碍

浏览器测试 __tests__/playwright/ 核实以下WCAG 2.2成功标准。 见 notes/goals/accessibility-criteria.md 财务报告和审定财务报表 notes/decisions/accessibility-audit-report.md 页:1 细节.

A11y 标准浏览器测试
1.3.1 信息和关系✓
1.3.2 有意义的顺序✓
2.1.1 键盘✓
2.1.2 无键盘陷阱✓
2.4.3 重点顺序✓
2.4.7 焦点可见✓
2.4.11 焦点不受干扰✓
3.2.1 聚焦✓
4.1.2 名称、作用、价值✓
4.1.3 状态信息✓
背景惰性( 模式对话框)✓
近因(拨号)✓

已知的限制

  • 萨法里 <dialog> 柔软相撞. 在 WebKit 上, a max-height: 100% 带一的弹性列 flex: 1 1 auto; overflow: auto 直接安置在a的儿童 Dialog 崩溃到 0px (单位:千美元) 块轴 fit-content 用户代理默认为无限期高地). Popover 套装 height: auto 避免这种情况; Dialog 故意不,让原始人没有布局 意见(见 notes/decisions/safari-popover-flex-collapse.md) (中文(简体) ). 一个消费者将这个形状建在 Dialog 应当给列一个确定的高度或 应用自己的 height: auto 复设于地.
    • TODO: 将它扩展为完整的公共消费者文件(建议的工作和 实例),放在顶层 Dialog 广泛采纳.

文档

见 notes/ 项目文件、结构决定、迁移记录和 审计报告。 这个 notes/README.md 提供完整的索引,包括 当前 移民状况 和链接 notes/decisions/migration-roadmap.md。 。 。 .

版本与发布记录

@atlaskit/top-layer 共发布 97 个版本,首次发布于 2026/03/25;过去 12 个月发布了 97 个版本。

版本发布日期距今
7.1.5latest2026/11/061 天前
7.1.42026/11/061 天前
7.1.32026/11/043 天前
7.1.22026/11/043 天前
7.1.12026/11/025 天前
7.1.02026/10/318 天前

关于 @atlaskit/top-layer 的常见问题

@atlaskit/top-layer 是什么?

基于 popover 和对话框的低层分层原始

如何安装 @atlaskit/top-layer?

在项目目录运行 npm install @atlaskit/top-layer,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:react(^18.2.0 || ^19.0.0)、react-dom(^18.2.0 || ^19.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@atlaskit/top-layer 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@atlaskit/top-layer 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@atlaskit/top-layer 可以商用吗?

@atlaskit/top-layer 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@atlaskit/top-layer 的下载量有多少?

根据 npm 官方下载统计,@atlaskit/top-layer 在 2026/10/07 – 2026/11/05 这 30 天内被下载 442,003 次,日均约 14,733 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@atlaskit/top-layer 还在维护吗?

最新版本 7.1.5 发布于 2026/11/06(1 天前);至今共发布 97 个版本,其中过去 12 个月发布了 97 个;首次发布于 2026/03/25。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。