threlte logo
@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 slot prop reflow:

<script lang="ts">
  import { Flex, Box } from '@threlte/flex'
  import { GLTF } from '@threlte/extras'
</script>

<Flex let:reflow>
  <Box>
    <GLTF
      src="/model.glb"
      on:load={() => {
        reflow()
      }}
    />
  </Box>
</Flex>

The reflow slot 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 slot props width and height
<script lang="ts">
  import { Flex } from '@threlte/flex'
</script>

<Flex
  let:width
  let:height
>
  <!-- ... -->
</Flex>
  • Using the reflow event
<script lang="ts">
  import { Flex } from '@threlte/flex'
</script>

<Flex
  on:reflow={({ width, height }) => {
    console.log(width, height)
  }}
>
  <!-- ... -->
</Flex>

Component Signature

Props

name
type
required
description

alignContent
"Auto" | "FlexStart" | "Center" | "FlexEnd" | "Stretch" | "Baseline" | "SpaceBetween" | "SpaceAround"
no

alignItems
"Auto" | "FlexStart" | "Center" | "FlexEnd" | "Stretch" | "Baseline" | "SpaceBetween" | "SpaceAround"
no

alignSelf
"Auto" | "FlexStart" | "Center" | "FlexEnd" | "Stretch" | "Baseline" | "SpaceBetween" | "SpaceAround"
no

aspectRatio
number
no

bottom
number | `${number}%`
no

class
string
no
declared classes will be resolved by a ClassParser declared on <Flex>

classParser
ClassParser
no
A ClassParser can be used to resolve Yoga Node Props based on classes passed to <Box> and <Flex> components.

direction
keyof typeof Direction
no

flex
number
no

flexBasis
number | "auto" | `${number}%`
no

flexDirection
"Column" | "ColumnReverse" | "Row" | "RowReverse"
no

flexGrow
number
no

flexShrink
number
no

flexWrap
"NoWrap" | "Wrap" | "WrapReverse"
no

gap
number
no

gapColumn
number
no

gapRow
number
no

height
number
no

height
number | "auto" | `${number}%`
no

justifyContent
"FlexStart" | "Center" | "FlexEnd" | "SpaceBetween" | "SpaceAround" | "SpaceEvenly"
no

left
number | `${number}%`
no

margin
number | "auto" | `${number}%`
no

marginBottom
number | "auto" | `${number}%`
no

marginLeft
number | "auto" | `${number}%`
no

marginRight
number | "auto" | `${number}%`
no

marginTop
number | "auto" | `${number}%`
no

maxHeight
number | `${number}%`
no

maxWidth
number | `${number}%`
no

minHeight
number | `${number}%`
no

minWidth
number | `${number}%`
no

order
number
no

padding
number | `${number}%`
no

paddingBottom
number | `${number}%`
no

paddingLeft
number | `${number}%`
no

paddingRight
number | `${number}%`
no

paddingTop
number | `${number}%`
no

plane
FlexPlane
no

reflowStage
Stage
no
The stage used for reflowing the layout.

right
number | `${number}%`
no

scaleFactor
number
no

top
number | `${number}%`
no

width
number
no

width
number | "auto" | `${number}%`
no

Events

name
payload
description

reflow
{ width: number, height: number }
Fired as soon as a reflow happened with the resulting width and height.