# @atlaskit/top-layer 中文文档

规范地址：https://npmcn.com/package/%40atlaskit/top-layer/

版本：7\.1\.5
npm 元数据更新时间：2026-11-06T09:39:17.071Z
中文译文更新时间：2026-11-07T02:42:27.790Z
软件包许可：Apache-2\.0

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40atlaskit/top-layer
原文对照：https://npmcn.com/package/%40atlaskit/top-layer/?lang=original
项目主页：https://atlassian.design/components/top-layer
源码仓库：https://bitbucket.org/atlassian/atlassian-frontend-mirror

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：1.2 MB，379 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- 运行依赖：10 个
- peer 依赖：react ^18\.2\.0 \|\| ^19\.0\.0，react-dom ^18\.2\.0 \|\| ^19\.0\.0
- 首次发布：2026-03-24T22:51:18.631Z
- 最新版本发布：2026-11-06T09:39:16.884Z
- 近 30 天下载量：442003（2026-10-07 至 2026-11-05，npm 官方下载统计）
- 已发布版本数：97（近 12 个月 97 个）

## 中文简介

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

## 安装

```sh
npm install @atlaskit/top-layer
```

也可以使用：`pnpm add @atlaskit/top-layer`、`yarn add @atlaskit/top-layer`、`bun add @atlaskit/top-layer`

## README

# @atlaskit/上层

使用土生土长的低层顶层原始人 [过量API](https://developer.mozilla.org/en-US/docs/Web/API/Popover_API) (单位:千美元)`popover="auto"`和 [`<dialog>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog) 键.

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

## 过量

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

```tsx
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`](https://npmcn.com/package/%40atlaskit/top-layer/notes/decisions/fit-available-space.md)。 。 。 .

## 对话框

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

```tsx
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` 打开层观察者.

```tsx
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`](https://developer.mozilla.org/en-US/docs/Web/CSS/@starting-style) 用于进入和进入 [`allow-discrete`](https://developer.mozilla.org/en-US/docs/Web/CSS/transition-behavior) 打开 `display`编号 :`overlay` 用于退出——不需要JavaScript动画协调.

### 流行动画

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

```tsx
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` 启用默认对话框的出入口动画 :

```tsx
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`](https://npmcn.com/package/%40atlaskit/top-layer/notes/goals/accessibility-criteria.md) 财务报告和审定财务报表 [`notes/decisions/accessibility-audit-report.md`](https://npmcn.com/package/%40atlaskit/top-layer/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`](https://npmcn.com/package/%40atlaskit/top-layer/notes/decisions/safari-popover-flex-collapse.md)) (中文(简体) ). 一个消费者将这个形状建在 `Dialog` 应当给列一个确定的高度或 应用自己的 `height: auto` 复设于地.
    -   TODO: 将它扩展为完整的公共消费者文件(建议的工作和 实例),放在顶层 `Dialog` 广泛采纳.

## 文档

见 [`notes/`](https://npmcn.com/package/%40atlaskit/top-layer/notes/) 项目文件、结构决定、迁移记录和 审计报告。 这个 [`notes/README.md`](https://npmcn.com/package/%40atlaskit/top-layer/notes/README.md) 提供完整的索引,包括 **当前 移民状况** 和链接 [`notes/decisions/migration-roadmap.md`](https://npmcn.com/package/%40atlaskit/top-layer/notes/decisions/migration-roadmap.md)。 。 。 .

## 常见问题

### @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 和提交记录判断。

