滚动区域 · ScrollableArea
承载独立滚动内容,并演示边界、粘性区域和溢出行为。
安装与前置条件
npm install @astryxdesign/core@0.7.1 @astryxdesign/theme-neutral@0.7.1 @stylexjs/stylex@0.19.0
需要 React 19+,按顺序导入基础 CSS 和主题,并设置 Theme Provider。参见开始使用。
示例与使用方式
- 滚动区域 · 综合展示 / 滚动 1:首先体验这个示例,再查看代码理解组件的组合方式。
- 滚动区域 · 滚动 2:可交互查看这一用法的行为,复制代码时保留它实际使用的属性与导入。
- 滚动区域 · 滚动 3:可交互查看这一用法的行为,复制代码时保留它实际使用的属性与导入。
- 滚动区域 · 粘性布局 / 分组 / 滚动 4:可交互查看这一用法的行为,复制代码时保留它实际使用的属性与导入。
- 滚动区域 · 粘性布局 / 滚动 5:可交互查看这一用法的行为,复制代码时保留它实际使用的属性与导入。
- 滚动区域 · 滚动 6:可交互查看这一用法的行为,复制代码时保留它实际使用的属性与导入。
API 与上游详细参考
优先使用 0.7.1 官方中文说明;上游尚未提供中文的条目保留英文。属性名、类型及默认值保持原生 API,不把示例状态名称当成组件属性。
Scrollable Area
Provides a native scroll viewport and a real observed content box. The viewport enters the tab order only while a requested logical axis is effectively scrollable, and containment applies only to effective axes.
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| axis | 'inline' | 'block' | 'both' | 'block' | Logical axis or axes where native scrolling is allowed. |
| label * | string | Accessible name for the viewport when it becomes keyboard scrollable. | |
| role | 'group' | 'region' | 'group' | Semantics for the named viewport. |
| overscroll | 'allow' | 'contain' | 'allow' | Whether effective axes continue scrolling an ancestor at their edge. |
| width | SizeValue | Width of the viewport; a number is interpreted as pixels, a string is used as-is. | |
| height | SizeValue | Height of the viewport; a number is interpreted as pixels, a string is used as-is. | |
| maxWidth | SizeValue | Maximum width of the viewport. | |
| minHeight | SizeValue | Minimum height of the viewport. | |
| stickyContainment | 'whenScrollable' | 'always' | 'whenScrollable' | Whether fitting content passes Sticky ownership to an outer container or deliberately keeps this viewport as the CSS Sticky boundary. |
| padding | 0 | 0.5 | 1 | 1.5 | 2 | 3 | 4 | 5 | 6 | 8 | 10 | 0 | Content padding on every logical edge; publishes matching inset geometry. |
| paddingInline | 0 | 0.5 | 1 | 1.5 | 2 | 3 | 4 | 5 | 6 | 8 | 10 | Logical inline-axis content padding; overrides padding on that axis. | |
| paddingInlineStart | 0 | 0.5 | 1 | 1.5 | 2 | 3 | 4 | 5 | 6 | 8 | 10 | Logical inline-start content padding; overrides broader padding values. | |
| paddingInlineEnd | 0 | 0.5 | 1 | 1.5 | 2 | 3 | 4 | 5 | 6 | 8 | 10 | Logical inline-end content padding; overrides broader padding values. | |
| paddingBlock | 0 | 0.5 | 1 | 1.5 | 2 | 3 | 4 | 5 | 6 | 8 | 10 | Logical block-axis content padding; overrides padding on that axis. | |
| paddingBlockStart | 0 | 0.5 | 1 | 1.5 | 2 | 3 | 4 | 5 | 6 | 8 | 10 | Logical block-start content padding; overrides broader padding values. | |
| paddingBlockEnd | 0 | 0.5 | 1 | 1.5 | 2 | 3 | 4 | 5 | 6 | 8 | 10 | Logical block-end content padding; overrides broader padding values. | |
| isFullBleed | boolean | false | Lets the viewport escape inherited container padding without changing content padding. |
| children | ReactNode | Content rendered inside the observed content box. | |
| xstyle | StyleXStyles | StyleX sizing and native scrollbar presentation overrides for the viewport. |
使用建议
- Give every area a concise label that identifies the content keyboard users will scroll.
- Choose
inline,block, orbothfrom content intent; the component maps the logical axes through writing mode and direction. - Keep the default
overscroll="allow"for nested areas unless the interaction deliberately needs containment. - Use
useScrollableAreainstead when a component already owns both a viewport and a suitable content box, or when children must remain direct flex/grid items or retain a definite percentage block-size basis. - ScrollableArea owns one normal block content box with a 100% minimum size. Inline and both-axis modes use max-content inline sizing, so intrinsic inline layout is intentionally wider than the viewport.
- Use logical padding props on the content box so nested full-bleed components receive the same inset geometry.
- Set
isFullBleedonly when the viewport itself should reach an ancestor container edge; it is off by default. - Set
stickyContainment="always"only when a fitting viewport should intentionally remain a Sticky boundary. - 避免:Hide the native scrollbar without another visible and operable overflow affordance.
- 避免:Add another overflow wrapper around ScrollableArea; one native viewport should own scrolling.
主题 API
{
"targets": [
{
"className": "astryx-scrollable-area",
"visualProps": [
"axis"
]
}
]
}
组件结构
- Viewport: The root native scroll container, accessible name owner, focus target while effective, and
astryx-scrollable-areatheme target. - Content box: A real inner layout box observed together with the viewport. For inline scrolling it uses max-content inline sizing with a 100% minimum.
示例的 StyleX 编译要求
ScrollableAreaOverscrollChaining、ScrollableAreaStickyGroupHeaders、ScrollableAreaStickyPassthrough 包含 stylex.create,需要配置 StyleX 源码编译流程。仅引入 Core 预编译 CSS 不足以运行这些示例样式,复制前请阅读样式与 Tailwind。