层级容器 · Layer
层级容器用于辅助功能场景。下面的官方示例展示原生用法与状态,属性名保持上游 API。
安装与前置条件
npm install @astryxdesign/core@0.7.1 @astryxdesign/theme-neutral@0.7.1 @stylexjs/stylex@0.19.0
需要 React 19+,按顺序导入基础 CSS 和主题,并设置 Theme Provider。参见开始使用。
示例与使用方式
- 层级容器 · 交互示例 1:首先体验这个示例,再查看代码理解组件的组合方式。
API 与上游详细参考
优先使用 0.7.1 官方中文说明;上游尚未提供中文的条目保留英文。属性名、类型及默认值保持原生 API,不把示例状态名称当成组件属性。
Layer
Layer utilities provide the app-level provider used by overlay systems. Use LayerProvider at the app root for toast/layer configuration; use higher-level Popover, HoverCard, or Tooltip APIs for most overlay UI. Rendered layer content, not the provider’s application subtree, uses theme body text defaults and exits ancestor surface/group membership. Establish intentional groups and complete required providers inside each layer. Every anchored layer keeps a gutter from each viewport edge — the spacing-4 step or the device safe-area inset, whichever is larger — and is capped to the viewport, never to the room beside its trigger: an explicit width renders at its size, flips when it does not fit beside the trigger, and slides into view when it fits on neither side. An app that floats a persistent bar over a viewport edge declares it once as inset on LayerProvider (blockStart, blockEnd, inlineStart, inlineEnd); each edge adds to that edge’s gutter for every anchored layer and moves the toast viewport by the same amount, and defaults to zero. The inset is app configuration, not a theme value.
使用建议
- Declare a persistent bar floating over the viewport once, as inset on LayerProvider; every anchored layer and toast then stays clear of it.
- Use LayerProvider once near the app root when you need shared toast/layer configuration.
- Build on higher-level components like Popover, HoverCard, and Tooltip for common overlay patterns.
- 避免:Add nested LayerProvider instances: nested providers are ignored and add unnecessary tree depth.
Layer Provider
App-level provider for layer systems such as toast viewports and imperative modals. Nested providers pass through.
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| children * | ReactNode | Application subtree that can use the shared layer context. | |
| toast | LayerToastConfig | Toast viewport configuration. Controls position, maxVisible, and a toast-only inset that overrides the provider inset per edge for toasts shown through useToast. | |
| inset | LayerInset | A persistent bar floating over a viewport edge, declared once: blockStart, blockEnd, inlineStart, inlineEnd as pixel numbers or CSS lengths. Each edge adds to the gutter every anchored layer keeps from that edge and moves the toast viewport by the same amount. Defaults to zero on every edge. |
useLayer
Core positioning hook for rendering overlay content using CSS Anchor Positioning and the Popover API. Use it as the foundation for custom popovers, hover cards, tooltips, and fixed-position layers when higher-level components are not enough. Both modes use theme body text defaults and end ancestor surface/group membership as a whole, including group-owned state. Explicit props and unrelated contexts remain unchanged. Apply intentional formatting through render styles or content, and establish complete content-local providers inside the rendered layer.
Parameters
| Parameter | Type | Description |
|---|---|---|
| mode | 'context' | 'fixed' | Positioning strategy: context uses CSS anchor positioning relative to a trigger ref; fixed uses explicit x/y coordinates. |
| onShow | () => void | Callback fired when the layer becomes visible. |
| onHide | () => void | Callback fired when the layer is hidden. |
| lightDismiss | boolean | Whether clicking outside should dismiss the layer using native popover light-dismiss behavior. |
| lazyMount | boolean | Context mode only. Wait until show() to resolve the inline/portal position and mount content; hide unmounts the content while the inert marker remains. |
Returns
[
{
"name": "ref",
"type": "RefCallback<HTMLElement> | undefined",
"description": "Trigger ref for context mode. Undefined in fixed mode."
},
{
"name": "anchorId",
"type": "string",
"description": "CSS anchor name for context mode positioning."
},
{
"name": "show",
"type": "() => void",
"description": "Imperatively show the layer."
},
{
"name": "hide",
"type": "() => void",
"description": "Imperatively hide the layer."
},
{
"name": "isOpen",
"type": "boolean",
"description": "Whether the layer is currently open."
},
{
"name": "id",
"type": "string",
"description": "Unique ID for aria-describedby or other ARIA relationships."
},
{
"name": "render",
"type": "(children: ReactNode, props: ContextRenderProps | FixedRenderProps) => ReactNode",
"description": "Render function for the popover element. Pass placement/alignment in context mode or x/y in fixed mode. Placement/alignment are logical: they map to the self-* position-area keyword family, which resolves against the popover's own inherited direction, so RTL contexts mirror automatically in pure CSS. Pass `positioning: \"custom\"` in context mode to author position styles yourself via `style` (e.g. explicit anchor() insets or an anchor-size() cover): the hook keeps the popover behavior and position-anchor wiring but derives no position styles, including the automatic RTL mirroring, which becomes your responsibility. Pass `offset` (a CSS length; a number is px) in context mode for clearance from the anchor: it applies to both edges of the placement axis, so the gap survives a flip. Layers are flush by default. Context mode first renders an inert `<template>` marker in matching server and client markup. The final layer stays at that JSX position if its parent is safe; otherwise it is portaled to the nearest ancestor outside paragraphs, links, buttons, inline formatting, and structurally restricted containers. The nearest safe host keeps CSS custom properties inheriting live, while the layer preserves direction and writing mode from its JSX position. By default this resolution occurs after hydration so closed-layer DOM remains available; `lazyMount` defers it until `show()` and unmounts the content again on hide while the marker remains. The Popover API promotes the layer to the top layer when shown, so it escapes ancestor clipping and stacking wherever it is hosted. When the layer would overflow the viewport, position-try fallbacks flip it to the opposite side; centered layers additionally slide along the alignment axis (span fallbacks) so they stay on-screen near viewport edges."
}
]
使用建议
- Use context mode for anchor-positioned overlays relative to a trigger element, and fixed mode for manually positioned overlays at specific coordinates.
- Build on higher-level components like Popover, HoverCard, and Tooltip for common overlay patterns.
- Rely on the Popover API top layer to escape ancestor clipping and stacking, and host the layer near its trigger rather than in the body so it inherits the trigger's theme cascade and keeps a natural focus order.
- 避免:Implement ARIA patterns directly in a Layer unless you also own the full accessibility behavior.