Yoga Docs: Rename website-next to website (#1613)

Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1613

So that GitHub links to edit a page point to the right place.

This will fail in OSS build until I switch the directory used by Vercel instance, but I am waiting to do that until ready to land, since that would cause other in progress changes to fail when exported.

Reviewed By: joevilches

Differential Revision: D54837857

fbshipit-source-id: 9bec90232dbe3ec8638568685671185d597fcf2d
This commit is contained in:
Nick Gerleman
2024-03-13 17:25:39 -07:00
committed by Facebook GitHub Bot
parent 108c2f30a2
commit 206b95aba5
88 changed files with 4 additions and 9 deletions

View File

@@ -0,0 +1,4 @@
{
"label": "Advanced",
"position": 3
}

View File

@@ -0,0 +1,89 @@
---
sidebar_position: 2
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import Playground from '@site/src/components/Playground';
# Containing block
Often times certain properties depend on a node beyond the
one it is applied to. An example of this is percentage lengths like `width: 50%` which
will set the width of a node to 50% of some other length. That other length is determined
by the size of the _containing block_. A containing block is not a Yoga-specific
concept and exists in the [web](https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block),
but since Yoga only implements a subset of web browser capabilities the behavior of
containing blocks is much more streamlined and it is helpful to frame it differently.
### Identifying the containing block of a node
- If the [position type](/docs/styling/position) of a node is static or relative then the containing block
is always the _content box_ of the parent. This is because in Yoga every node is a
flex container and therefore establishes a formatting context which would form a
containing block on the web. The content box is formed by the node without margin, padding, or borders.
- If the [position type](/docs/styling/position) of a node is absolute then the containing block will be
the _padding box_ (the content box plus padding) of any of:
- The nearest non-static ancestor.
- The nearest ancestor which is configured to always form a containing block. This
is helpful for supporting things outside of Yoga which would form a containing block
on the web, such as [filters](https://developer.mozilla.org/en-US/docs/Web/CSS/filter)
or [transforms](https://developer.mozilla.org/en-US/docs/Web/CSS/transform). This
is done by calling the corresponding API for the lanuage you are working in.
<Tabs groupId="language">
<TabItem value="cpp" label="C/C++">
```cpp
YGNodeSetAlwaysFormsContainingBlock(node, true /*alwaysFormsContainingBlock*/);
```
</TabItem>
<TabItem value="java" label="Java">
```java
node.setAlwaysFormsContainingBlock(true /*alwaysFormsContainingBlock*/);
```
</TabItem>
<TabItem value="ts" label="Typescript">
```typescript
node.setAlwaysFormsContainingBlock(true /*alwaysFormsContainingBlock*/);
```
</TabItem>
</Tabs>
- The root if none of the above apply. Note that this is different from the web
which has the notion of the _initial containing block_ that depends on the size
of the viewport.
- If the node in question is the root then there is no containing block, but it will
use the `availableWidth` and `availableHeight` that is passed in to the call to
[`CalculateLayout`](/docs/getting-started/laying-out-a-tree).
### What the containing block affects
- Any percentage-based lengths will depend on the size of the containing block.
Specifically the [height](/docs/styling/width-height), top, and bottom properties will use the height of the
containing block. The [width](/docs/styling/width-height), left, right, [margin](/docs/styling/margin-padding-border),
and [padding](/docs/styling/margin-padding-border) will use the width of the containing block.
- Any insets (left, right, top, bottom, etc.) applied to absolute nodes will be
relative to the corresponding edge of the containing block.
<Playground code={`<Layout config={{useWebDefaults: false}}>
<Node
style={{
width: 200,
height: 200,
padding: 10
}}>
<Node
style={{
height: 100,
width: 100,
position: 'static'
}}>
<Node
style={{
height: 25,
width: '50%',
bottom: 10,
position: 'absolute'
}}
/>
</Node>
</Node>
</Layout>`} />

View File

@@ -0,0 +1,106 @@
---
sidebar_position: 3
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
# Integrating with external layout systems
It is typical for applications to have content whose size may be dependent on factors not expressible inside of Yoga. This can often include text, or views which are rendered or laid out using a different system. Yoga allows leaf nodes to delegate to a different layout system via **Measure Functions**.
## Setting a measure function
A measure function (callback) is set on a node, to instruct Yoga to ask an external layout system for sizing of a given structure when it is time to measure the leaf node.
<Tabs groupId="language">
<TabItem value="cpp" label="C/C++">
Measure functions in the C/C++ APIs are represented as C function pointers and do not carry state. A Yoga node may be associated with an external structure by setting a **context** on the node. This is a `void*` tag, which may be read during callbacks.
```cpp
Widget widget{};
YGNodeSetContext(node, &w);
YGNodeSetMeasureFunc(node, &measureWidget);
```
</TabItem>
<TabItem value="java" label="Java">
Measure functions are represented by the `YogaMeasureFunction` interface. This interface can be fulfilled by an explicit subclass, an anonymous inner class, or a lambda. Framework data may be associated with the underlying measure function, or a global measure function may be used, with data set on the underlying Yoga node.
```java
Widget widget = new Widget();
node.setData(widget);
node.setMeasureFunction(MEASURE_WIDGET);
```
</TabItem>
<TabItem value="js" label="JavaScript">
Measure functions are represented as an anonymous function, which may be bound to framework data.
```ts
const widget = new Widget();
node.setMeasureFunction((width, widthMode, height, heightMode) => {
...
});
```
</TabItem>
</Tabs>
## Responding with measurements
Yoga will call a node's measure function if the node does not otherwise have a definite dimension. This measure function is given the available space in each axis if constrained, with border and padding already subtracted.
:::warning
Yoga is not guaranteed to call a node's measure function if the node already has a definite dimension. Final content dimensions for a node should be read from the node's layout results, instead of caching measure function results.
:::
Each axis is passed a `MeasureMode` as a constraint:
1. `Exactly`: The measured length of the given axis is imposed to be the available length. This corresponds to [`stretch-fit`](https://www.w3.org/TR/css-sizing-3/#stretch-fit-size) sizing.
2. `Undefined`: The measured length in the given axis should be the maximum natural length of the content. This corresponds to [`max-content`](https://www.w3.org/TR/css-sizing-3/#max-content) sizing.
3. `AtMost`: The measured length in the given axis should be the minimum of the available space in the axis, and the natural content size. This corresponds to [`fit-content`](https://www.w3.org/TR/css-sizing-3/#fit-content-size) sizing.
## Invalidating measurements
Yoga must be notified if the content associated with a node changes in a way which may effect measurement.
<Tabs groupId="language">
<TabItem value="cpp" label="C/C++">
```cpp
YGNodeMarkDirty(node);
```
</TabItem>
<TabItem value="java" label="Java">
```java
node.dirty();
```
</TabItem>
<TabItem value="js" label="JavaScript">
```ts
node.markDirty();
```
</TabItem>
</Tabs>

View File

@@ -0,0 +1,75 @@
---
sidebar_position: 1
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
# Incremental layout
Most real-world UIs are not static. Yoga trees may be laid out incrementally to avoid large work when only a small portion of the UI changes. Yoga will automatically mark a node and its ancestors as "dirty" if the node's style or children are changed. During the first layout, all nodes are considered dirty, and every node is visited. On subsequent layout, any nodes that are not dirty are skipped, so long as their parent constraints have not changed.
Yoga exposes whether the layout of a node or its children have changed via a `HasNewLayout` flag. This flag may be read when applying Yoga layout results to avoid traversing any subtrees where there are no updates.
<Tabs groupId="language">
<TabItem value="cpp" label="C/C++">
```cpp
void applyLayout(YGNodeRef node) {
if (!YGNodeHasNewLayout(node)) {
return;
}
// Reset the flag
YGNodeSetHasNewLayout(node, false);
// Do the real work
...
for (size_t i = 0; i < YGNodeGetChildCount(node); i++) {
applyLayout(YGNodeGetChild(node, i));
}
}
```
</TabItem>
<TabItem value="java" label="Java">
```java
void applyLayout(YogaNode node) {
if (!node.hasNewLayout()) {
return;
}
// Reset the flag
node.markLayoutSeen();
// Do the real work
...
for (int i = 0; i < node.getChildCount(); i++) {
applyLayout(node.getChildAt(i));
}
}
```
</TabItem>
<TabItem value="js" label="JavaScript">
:::danger
Yoga's JavaScript bindings are missing support for acessing the `HasNewLayout` flag. https://github.com/facebook/yoga/issues/681
:::
</TabItem>
</Tabs>
In the below example, we start with an already laid out tree. The style of `F` is then modified, dirtying the node and its ancestors. After layout, the dirtied nodes, and any effected children, are marked as having new layout.
| Clean tree | Dirtied tree | Has new layout |
| - | - | - |
| ![Clean tree](../img/invalidation-clean-tree.svg) | ![Clean tree](../img/invalidation-dirtied-tree.svg) | ![Has new layout](../img/invalidation-new-layout-tree.svg) |