Description
Flex.Container
is a building block for CSS flexbox based layout of contents and components.
Ideally, use Flex.Item or Card for you inner wrappers.
import { Flex } from '@dnb/eufemia'render(<Flex.Container><Flex.Item>content</Flex.Item></Flex.Container>,)
How spacing is applied
Nested components should preferably support spacing properties.
When a element or component was given, that does not support spacing, it will still work out of the box as it gets wrapped in a spacing block.
You may else wrap your custom component in a Flex.Item
– this way, you still can change the spacing per component basis.
Technically, Flex.Container
checks if a nested component has a property called _supportsSpacingProps
. So if you have a component that supports the spacing properties, you can add this property ComponentName._supportsSpacingProps = true
. If you provide false
, it will not support spacing.
If the component is a wrapper component, and you want its children to support spacing, you can add this property ComponentName._supportsSpacingProps = 'children'
.
But for simplicity, you can use the HOC Flex.withChildren
:
const Wrapper = Flex.withChildren(({ children }) => {return <div>{children}</div>})render(<Flex.Container direction="vertical"><Item /><Wrapper><Item /><Item /></Wrapper><Item /></Flex.Container>,)
Horizontal and Vertical aliases
For shortening the usage of direction="..."
, you can use:
<Flex.Vertical>
instead of<Flex.Container direction="vertical">
<Flex.Vertical><Flex.Item>part of vertical alignment</Flex.Item><Flex.Item>part of vertical alignment</Flex.Item></Flex.Vertical>
<Flex.Horizontal>
instead of<Flex.Container direction="horizontal">
<Flex.Horizontal><Flex.Item>part of horizontal alignment</Flex.Item><Flex.Item>part of horizontal alignment</Flex.Item></Flex.Horizontal>
Demos
No properties
<Flex.Container> <Flex.Item> <TestElement>FlexItem</TestElement> </Flex.Item> <Flex.Item> <TestElement>FlexItem</TestElement> </Flex.Item> <Flex.Item> <TestElement>FlexItem</TestElement> </Flex.Item> <Flex.Item> <TestElement>FlexItem</TestElement> </Flex.Item> </Flex.Container>
Horizontal Flex.Item
<Flex.Container> <Flex.Item> <TestElement>FlexItem</TestElement> </Flex.Item> <Flex.Item> <TestElement>FlexItem</TestElement> </Flex.Item> <Flex.Item> <TestElement>FlexItem</TestElement> </Flex.Item> <Flex.Item> <TestElement>FlexItem</TestElement> </Flex.Item> </Flex.Container>
justify="center"
Horizontal Flex.Item, <Flex.Container justify="center"> <Flex.Item> <TestElement>FlexItem</TestElement> </Flex.Item> <Flex.Item> <TestElement>FlexItem</TestElement> </Flex.Item> <Flex.Item> <TestElement>FlexItem</TestElement> </Flex.Item> <Flex.Item> <TestElement>FlexItem</TestElement> </Flex.Item> </Flex.Container>
justify="flex-end"
Horizontal Flex.Item, <Flex.Container justify="flex-end"> <Flex.Item> <TestElement>FlexItem</TestElement> </Flex.Item> <Flex.Item> <TestElement>FlexItem</TestElement> </Flex.Item> <Flex.Item> <TestElement>FlexItem</TestElement> </Flex.Item> <Flex.Item> <TestElement>FlexItem</TestElement> </Flex.Item> </Flex.Container>
size
and grow
Horizontal with <Flex.Horizontal> <Flex.Item size={3}> <Card>Card contents</Card> </Flex.Item> <Flex.Item size={4}> <Card>Card contents</Card> </Flex.Item> <Flex.Item size={5}> <Card>Card contents</Card> </Flex.Item> <Flex.Item grow> <Card>Card contents</Card> </Flex.Item> <Flex.Item grow> <Card>Card contents</Card> </Flex.Item> <Flex.Item grow> <Card>Card contents</Card> </Flex.Item> </Flex.Horizontal>
Horizontal Field.String
Will wrap on small screens.
<Flex.Container> <Field.String label="Label" value="Foo" /> <Field.String label="Label" value="Foo" width="medium" /> </Flex.Container>
Vertical Flex.Item
<Flex.Container direction="vertical"> <Flex.Item> <TestElement>FlexItem</TestElement> </Flex.Item> <Flex.Item> <TestElement>FlexItem</TestElement> </Flex.Item> <Flex.Item> <TestElement>FlexItem</TestElement> </Flex.Item> <Flex.Item> <TestElement>FlexItem</TestElement> </Flex.Item> </Flex.Container>
Vertical aligned Card
<Flex.Container direction="vertical"> <Card>Card contents</Card> <Card>Card contents</Card> <Card>Card contents</Card> </Flex.Container>
Vertical line divider
Heading
<Card> <Flex.Container direction="vertical" divider="line"> <Form.SubHeading>Heading</Form.SubHeading> <Field.String label="Label" value="Value" /> <Field.String label="Label" value="Value" /> </Flex.Container> </Card>
Vertical aligned Field.String
<Card> <Flex.Container direction="vertical"> <Field.String label="Label" value="Foo" /> <Field.String label="Label" value="Foo" /> </Flex.Container> </Card>
Framed line dividers
This example shows how to use the Flex.Container
component to create a framed line divider (line-framed
), which includes a line before the first item and above the last item.
const Item = () => ( <Flex.Stack divider="line-framed" spacing="x-small"> <TestElement>FlexItem</TestElement> <TestElement>FlexItem</TestElement> </Flex.Stack> ) render( <Flex.Horizontal rowGap={false}> <Item /> <Item /> <Item /> </Flex.Horizontal>, )
Flex.withChildren
const Wrapper = Flex.withChildren(({ children }) => { return <div>{children}</div> }) render( <Flex.Container direction="vertical"> <TestElement>FlexItem 1</TestElement> <Wrapper> <TestElement>FlexItem 2</TestElement> <TestElement>FlexItem 3</TestElement> </Wrapper> <TestElement>FlexItem 4</TestElement> </Flex.Container>, )