ScrollBox

一个可滚动容器,支持水平和垂直滚动、粘性滚动行为、视口裁剪和可自定义的滚动条。

基本用法

Renderable API

import { ScrollBoxRenderable, TextRenderable, BoxRenderable, createCliRenderer } from "@opentui/core"

const renderer = await createCliRenderer()

const scrollbox = new ScrollBoxRenderable(renderer, {
  id: "scrollbox",
  width: 40,
  height: 20,
})

// Add content to the scrollbox
for (let i = 0; i < 100; i++) {
  scrollbox.add(
    new BoxRenderable(renderer, {
      id: `item-${i}`,
      width: "100%",
      height: 2,
      backgroundColor: i % 2 === 0 ? "#292e42" : "#2f3449",
    }),
  )
}

renderer.root.add(scrollbox)

Construct API

import { ScrollBox, Box, Text, createCliRenderer } from "@opentui/core"

const renderer = await createCliRenderer()

renderer.root.add(
  ScrollBox(
    {
      width: 40,
      height: 20,
    },
    ...Array.from({ length: 100 }, (_, i) =>
      Box(
        { width: "100%", padding: 1, backgroundColor: i % 2 === 0 ? "#292e42" : "#2f3449" },
        Text({ content: `Item ${i}` }),
      ),
    ),
  ),
)

粘性滚动

启用粘性滚动可将内容固定在边缘位置,当新内容出现时自动保持。适用于日志查看器或聊天界面。

const scrollbox = new ScrollBoxRenderable(renderer, {
  id: "logs",
  width: 60,
  height: 20,
  stickyScroll: true,
  stickyStart: "bottom", // New content will keep the view scrolled to bottom
})

粘性位置

  • "bottom" - 保持滚动到底部(聊天/日志的默认设置)
  • "top" - 保持滚动到顶部
  • "left" - 保持滚动到左侧
  • "right" - 保持滚动到右侧

当你滚动离开粘性位置时,粘性行为会暂停,直到你滚动回到粘性边缘。

双向滚动

启用两个方向的滚动:

const scrollbox = new ScrollBoxRenderable(renderer, {
  id: "canvas",
  width: 60,
  height: 30,
  scrollX: true,
  scrollY: true,
})

默认情况下,scrollYtruescrollXfalse

视口裁剪

启用视口裁剪以在处理大量内容时获得更好的性能。启用后,ScrollBox 仅渲染可见的子元素:

const scrollbox = new ScrollBoxRenderable(renderer, {
  id: "large-list",
  width: 40,
  height: 20,
  viewportCulling: true, // Only render visible items
})

视口裁剪会跳过屏幕外子元素的渲染调用,因此它们的 renderBeforerenderAfter 钩子不会执行。不要让布局或状态依赖渲染钩子;如果每个子元素都必须执行渲染钩子,请禁用 viewportCulling

自定义滚动条

使用嵌套选项设置滚动条样式:

const scrollbox = new ScrollBoxRenderable(renderer, {
  id: "styled-scroll",
  width: 40,
  height: 20,
  scrollbarOptions: {
    showArrows: true,
    trackOptions: {
      foregroundColor: "#7aa2f7",
      backgroundColor: "#414868",
    },
  },
  // Or customize vertical and horizontal separately
  verticalScrollbarOptions: {
    trackOptions: { backgroundColor: "#333" },
  },
  horizontalScrollbarOptions: {
    trackOptions: { backgroundColor: "#333" },
  },
})

自定义子组件

ScrollBox 包含多个内部组件,你可以分别设置它们的样式:

const scrollbox = new ScrollBoxRenderable(renderer, {
  id: "custom-scroll",
  width: 40,
  height: 20,
  rootOptions: {
    backgroundColor: "#24283b",
  },
  wrapperOptions: {
    backgroundColor: "#1f2335",
  },
  viewportOptions: {
    backgroundColor: "#1a1b26",
  },
  contentOptions: {
    backgroundColor: "#16161e",
  },
})

滚动方法

scrollBy

按相对量滚动:

// Scroll down 5 lines
scrollbox.scrollBy(5)

// Scroll with both x and y
scrollbox.scrollBy({ x: 10, y: 5 })

// Scroll by viewport (page)
scrollbox.scrollBy(1, "viewport")

scrollTo

滚动到绝对位置:

// Scroll to top
scrollbox.scrollTo(0)

// Scroll to specific position
scrollbox.scrollTo({ x: 0, y: 100 })

scrollChildIntoView

滚动最小距离以使嵌套的子元素在视口中可见。该方法使用 DOM 风格的”最近”行为:如果子元素已经在视口内,则调用不会产生任何效果;否则会滚动到最近的边缘以显示该子元素。

scrollbox.scrollChildIntoView("table-row-42")

当你聚焦屏幕外的元素(搜索结果、新插入的表单字段等)并希望将其带入视图而不超出需要地移动滚动位置时,可以使用此方法。

键盘导航

当获得焦点时,ScrollBox 响应以下键盘输入:

  • 方向键 - 按行滚动
  • Page Up/Down - 按页滚动
  • Home/End - 滚动到起始/末尾位置

属性

属性类型默认值描述
scrollXbooleanfalse启用水平滚动
scrollYbooleantrue启用垂直滚动
stickyScrollbooleanfalse将滚动位置固定在边缘
stickyStart"top" | "bottom" | "left" | "right"-要固定的边缘方向
viewportCullingbooleantrue仅渲染可见的子元素
scrollAccelerationScrollAcceleration-自定义滚动加速算法
rootOptionsBoxOptions-根容器的样式选项
wrapperOptionsBoxOptions-外层包装器的样式选项
viewportOptionsBoxOptions-视口的样式选项
contentOptionsBoxOptions-内容容器的样式选项
scrollbarOptionsScrollBarOptions-两个滚动条的通用选项
verticalScrollbarOptionsScrollBarOptions-垂直滚动条的专用选项
horizontalScrollbarOptionsScrollBarOptions-水平滚动条的专用选项

额外属性

属性类型描述
scrollTopnumber当前垂直滚动位置(可读写)
scrollLeftnumber当前水平滚动位置(可读写)
scrollWidthnumber总可滚动宽度(只读)
scrollHeightnumber总可滚动高度(只读)

内部组件

ScrollBox 暴露其内部组件以供高级使用:

scrollbox.wrapper // BoxRenderable - outer wrapper
scrollbox.viewport // BoxRenderable - visible area
scrollbox.content // ContentRenderable - holds children
scrollbox.horizontalScrollBar // ScrollBarRenderable
scrollbox.verticalScrollBar // ScrollBarRenderable