@threlte/flex
<Flex>
The component <Flex>
is used to create the root of a flex layout. It creates
the root node for Yoga and provides a context for all
child <Box>
components to resolve their layout.
Usage
The <Flex>
component resembles the root display: flex
container in CSS. It
can be used to create a flex layout with the child components <Box>
.
Since there’s no viewport to fill, you must specify the size of the container
with the props width
and height
.
<script lang="ts">
import { Flex } from '@threlte/flex'
</script>
<div style="display: flex; width: 100px; height: 100px">
<!-- ... -->
</div>
<!-- translates to this -->
<Flex
width={100}
height={100}
>
<!-- ... -->
</Flex>
Layout Direction
Layout direction specifies the direction in which children and text in a
hierarchy should be laid out. Layout direction also effects what edge start
and
end
refer to. By default Yoga lays out with LTR layout direction.
<Flex direction="RTL">
<!-- ... -->
</Flex>
Layout precision
Yoga uses integers for layout computation. Because in Three.js we’re dealing
with floating point numbers, all values are internally multiplied by a
scaleFactor
of 1000
to increase precision which is suitable for most use
cases. Depending on the size of your layout, you might need to increase the
scaleFactor
to 10000
or 100000
to avoid layout issues.
<Flex scaleFactor={100000}>
<!-- ... -->
</Flex>
Using CSS Classes
A classParser
can be used to resolve Yoga Node Props based on classes passed
to <Box>
and <Flex>
components. This is useful if you want to use a CSS-like
syntax to define your layout. You can define your own ClassParser
using the
method createClassParser
or by
using a parser provided, for instance the Tailwind CSS parser
tailwindParser
.
<script lang="ts">
import { Flex, tailwindParser } from '@threlte/flex'
</script>
<Flex classParser={tailwindParser}>
<!-- ... -->
</Flex>
Layout Orientationu
Yoga computes the layout on a 2D plane. The elements will be positioned in the
2D plane given by the two axes. By default, the layout plane is the xy
plane.
You can change the layout plane to yz
or xz
by setting the prop plane
.
<Flex plane="yz">
<!-- ... -->
</Flex>
Layout Reflow
Yoga is a layout engine that computes the layout of a
node tree. If a node (i.e. a <Box>
component) is added or removed
from the tree, or if a node changes its properties, the layout of the component
tree needs to be recomputed. This is called a reflow.
A reflow is triggered automatically when:
<Flex>
props changes (width
,height
,justifyContent
, …)<Box>
props changes (justifyContent
,flex
, …)- A
<Box>
component mounts or unmounts
Because the width and height of a flex layout item may be calculated from its
bounding box, the initial layout may be incorrect, for instance if a model loads
into view after the initial layout has been computed. To manually request a
reflow, you can use the snippet prop reflow
:
<script lang="ts">
import { Flex, Box } from '@threlte/flex'
import { GLTF } from '@threlte/extras'
</script>
<Flex>
{#snippet children({ reflow })}
<Box>
<GLTF
src="/model.glb"
onload={() => reflow()}
/>
</Box>
{/snippet}
</Flex>
The reflow
snippet prop is also available on <Box>
components to enable
encapsulated child components to easily request a reflow.
You may also use the hook useReflow
to request
a reflow.
Reflow Stage
By default, the reflow of the layout is happening in Threlte’s
mainStage. To change in
what stage the layout should reflow, use the prop reflowStage
:
<script lang="ts">
import { useStage, useThrelte } from '@threlte/core'
import { Flex } from '@threlte/flex'
const { mainStage, renderStage } = useThrelte()
const reflowStage = useStage('reflow-stage', {
after: mainStage,
before: renderStage
})
</script>
<Flex {reflowStage}>
<!-- ... -->
</Flex>
Content Dimensions
Although the width and the height of the <Flex>
component are required, the
dimensions of the contents of the <Flex>
component will be measured after a
layout reflow and can be retrieved using the following methods:
- Using the hook
useDimensions
- Using the snippet props
width
andheight
<script lang="ts">
import { Flex } from '@threlte/flex'
</script>
<Flex>
{#snippet children({ width, height })}
<!-- ... -->
{/snippet}
</Flex>
- Using the
reflow
event
<script lang="ts">
import { Flex } from '@threlte/flex'
</script>
<Flex
onreflow={({ width, height }) => {
console.log(width, height)
}}
>
<!-- ... -->
</Flex>