Skip to content

feat: add scrollable UI transform and UiScrollResult#412

Open
kuruk-mm wants to merge 3 commits into
mainfrom
feat/ui-scroll-bar
Open

feat: add scrollable UI transform and UiScrollResult#412
kuruk-mm wants to merge 3 commits into
mainfrom
feat/ui-scroll-bar

Conversation

@kuruk-mm
Copy link
Copy Markdown
Member

@kuruk-mm kuruk-mm commented May 20, 2026

Summary

Proposes adding scrollable UI containers and a programmatic way to observe / control their scroll state. Verified against the reference renderer in bevy-explorer (crates/scene_runner/src/update_world/scene_ui/mod.rs, crates/ui_core/src/scrollable.rs), which already wires these fields end-to-end.

What this adds

PBUiScrollResult — new component (ecs_component_id = 1202)

Renderer → scene. The renderer writes the viewport's current scroll offset back to the scene whenever the user scrolls (wheel, drag, or programmatic move), letting scene logic react to scroll state.

message PBUiScrollResult {
  decentraland.common.Vector2 value = 1; // current scroll offset (h, v)
}

ui_transform.proto additions

ShowScrollBar enum — which scroll bars are visible on a scrollable node:

  • SSB_BOTH (default) — horizontal + vertical
  • SSB_ONLY_VERTICAL
  • SSB_ONLY_HORIZONTAL
  • SSB_HIDDEN — no bars (content still scrollable via wheel/drag)

ScrollPositionValue messageoneof:

  • position (Vector2) — literal scroll offset
  • reference (string) — element_id of a descendant; the renderer scrolls the viewport so that element is visible

Three new optional fields on PBUiTransform:

Field # Purpose
element_id 74 Unique name for this UI element (HTML-id-like). Registered in a named-element table so other components/RPCs can refer to it by name. Today consumed by ScrollPositionValue.reference and the UI focus RPC. Default: empty.
scroll_position 75 Scroll offset of this node's scroll viewport. Only meaningful when overflow = YGO_SCROLL. Default: position=(0,0).
scroll_visible 76 Which scroll bars to render. Default: SSB_BOTH.

Proposed usage

1. Make a node scrollable

UiTransform.create(entity, {
  width: 300, height: 200,
  overflow: YGOverflow.YGO_SCROLL,     // required for scroll to engage
  scrollVisible: ShowScrollBar.SSB_ONLY_VERTICAL,
})

2. Set scroll position imperatively

UiTransform.createOrReplace(entity, {
  overflow: YGOverflow.YGO_SCROLL,
  scrollPosition: { value: { $case: 'position', position: { x: 0, y: 250 } } },
})

3. Scroll a named child into view

UiTransform.create(childEntity, { elementId: 'section-3', parent })

UiTransform.createOrReplace(parent, {
  overflow: YGOverflow.YGO_SCROLL,
  scrollPosition: { value: { $case: 'reference', reference: 'section-3' } },
})

4. React to user scrolling

const result = UiScrollResult.getOrNull(entity)
if (result?.value) {
  // result.value is the current { x, y } scroll offset
}

Test plan

  • make buf-lint passes
  • make buf-build passes
  • Confirm downstream SDK codegen picks up the new symbols
  • Renderer (bevy-explorer / Unity) tested against a scene exercising literal scroll, reference scroll, and PBUiScrollResult read-back

Cherry-picks scroll-related additions from protocol-squad:
- New PBUiScrollResult component (ecs_component_id 1100)
- ShowScrollBar enum and ScrollPositionValue message
- element_id, scroll_position, scroll_visible fields on PBUiTransform
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 20, 2026

Test this pull request

  • The @dcl/protocol package can be tested in scenes by running
    npm install "https://sdk-team-cdn.decentraland.org/@dcl/protocol/branch//dcl-protocol-1.0.0-26197255415.commit-323091f.tgz"

element_id is the element's own unique name (HTML-id-like), registered in
a named-node table consumed by ScrollPositionValue.reference and the UI
focus RPC — not merely a "reference for scroll_position".
@kuruk-mm kuruk-mm changed the title feat: add scroll bar support to UI transform feat: add scrollable UI transform and UiScrollResult May 20, 2026
Match the value already in use on protocol-squad so the two branches
agree on the component ID.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant