Add scrolling primitives: contentOffsetX/contentOffsetY props and client/scroll size metrics - #988
Open
costajohnt wants to merge 5 commits into
Open
Add scrolling primitives: contentOffsetX/contentOffsetY props and client/scroll size metrics#988costajohnt wants to merge 5 commits into
contentOffsetX/contentOffsetY props and client/scroll size metrics#988costajohnt wants to merge 5 commits into
Conversation
…ent/scroll size metrics Fixes vadimdemedes#765
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This implements the scrolling primitives sketched in #765, following the direction there: core primitives only, so a
ScrollViewcan be built in userland (example included in the readme).contentOffsetX/contentOffsetYprops onBox. Children are shifted left/up by the given number of columns/rows at render time. Combined withoverflow="hidden", this is the scroll mechanism. Layout is untouched, the offset is applied inrenderNodeToOutputwhen recursing into children, so Yoga sees nothing new.measureElement()now also returnsclientWidth/clientHeight(size excluding borders) andscrollWidth/scrollHeight(content extent including overflow, computed from child layout extents and clamped to be at least the client size, matching DOM semantics). These extend thex/y/width/heightshape from feat: extend measureElement() to return position coordinates #968.useBoxMetrics()returns the same four new fields, so a userland ScrollView can be fully reactive to content changes via the existing layout listener.examples/scroll) wrap the content in aflexShrink={0}container. Without it, Yoga squeezes the children into the fixed-height viewport and there is nothing to scroll; the recipe notes this explicitly since it is the first thing anyone building a ScrollView will hit.One deliberate divergence from the snippet in #765: child extents are measured relative to the inside of the container's border (parent border offsets are subtracted), so
scrollWidth === clientWidthwhen content exactly fits a bordered box. The issue snippet measured against the outer edge, which over-reports the scroll extent by the border width.Deliberately not included, per the discussion in #765: scrollbars, overflow indicators, an imperative scroll API, and any built-in
ScrollViewcomponent. Offsets are also not clamped to the content extent, clamping policy belongs to the userland component (the readme example clamps viascrollHeight - clientHeight).Tests: rendering tests for vertical/horizontal offsets, offsets inside borders, nested offset containers, offset beyond content, and a zero-offset behavior lock; metric tests for client/scroll sizes with overflowing content, borders, and content that grows after mount. All fail on
masterwithout the change (except the behavior lock). Verified manually in a real terminal with the included example (both axes, clamping at all edges).Also relevant to #222.