Composition

Specification

Component that represents a layout composition.

Props

Composition inherits from Box component, thus is accepts the same props and CSS Grid props on top.
Prop name
Type
Description
inline
boolean
Renders composition with display: inline-grid.
Composition supports all Prop aliases.

Usage

Define templates

Composition begins by defining a template string that consists of layout (grid) areas.
1
const areasMobile = `
2
logo
3
menu
4
`
Copied!
Template string is just an alias for grid-template-areas.
Since Atomic layout comes with responsive built-in, you can define multiple layout templates for a single composition based on the breakpoints of your layout.
1
const areasTablet = `
2
logo menu
3
search search
4
`
Copied!

Render Composition

Once layout templates are defined, pass them as the respective areas props of the Composition. Each area in the template is turned into a React component and being exposed as an argument property of the children function:
1
<Composition
2
areas={areasMobile}
3
areasMd={areasTablet}>
4
{(Areas) => (
5
<>
6
<Areas.Logo>...</Areas.Logo>
7
<Areas.Search>...</Areas.Search>
8
<Areas.Menu>...</Areas.Menu>
9
</>
10
)}
11
</Composition>
Copied!
Generated area components are exposed as unique capitalized keys of the children function.

Configuration

Composition is meant to be configurable. There is a set of Prop aliases you can apply to make composition suit your needs. For example, we can specify a templateCols prop to control the behavior of our columns on different breakpoints:
1
<Composition
2
areas={areasMobile}
3
areasMd={areasTablet}
4
templateCols="1fr auto"
5
templateColsMd="1fr 1fr" />
Copied!

Examples

Template-less composition

Composition can be used without any templates. In that case it serves as a display: grid wrapper for its children elements. All Prop aliases still apply.
1
import React from 'react'
2
import { Composition } from 'atomic-layout'
3
4
export const Header = () => (
5
<Composition templateCols="repeat(3, 1fr)">
6
<Logo />
7
<Menu />
8
<Actions />
9
</Composition>
10
)
Copied!
Note that using the Box component is recommended when you don't wish to control elements composition, but want to distribute spacial relation of the parent element.

Simple composition

src/components/ArtistCard/index.jsx
1
import React from 'react'
2
import { Composition } from 'atomic-layout'
3
4
const areasMobile = `
5
thumbnail
6
heading
7
content
8
`
9
10
const areasDesktop = `
11
thumbnail heading
12
thumbnail content
13
`
14
15
export const ArtistCard = ({ title, imageUrl, description }) => (
16
<Composition
17
areas={areasMobile}
18
areasMd={areasDesktop}
19
gap={10}
20
gapMd={20}
21
padding={10}>
22
{(Areas) => (
23
<>
24
<Areas.Thumbnail>
25
<img src={imageUrl} alt={title} />
26
</Areas.Thumbail>
27
<Areas.Heading>
28
<h3>{title}</h3>
29
</Areas.Heading>
30
<Areas.Content>
31
<p>{description}</p>
32
</Areas.Content>
33
</>
34
)}
35
</Composition>
36
)
Copied!

Nested composition

components/ArtistCard/index.jsx
1
import React from 'react'
2
import { Composition } from 'atomic-layout'
3
import ArtistContent from './ArtistContent'
4
5
const areasMobile = `
6
thumbnail
7
content
8
`
9
10
export const ArtistCard = ({
11
title,
12
description,
13
publishDate,
14
imageUrl,
15
onShareClick
16
}) => (
17
<Composition areas={areasMobile}>
18
{(Areas) => (
19
<>
20
<Areas.Thumbnail>
21
<img src={imageUrl} alt={title} />
22
</Areas.Thumbnail>
23
<Areas.Content>
24
<ArtistContent
25
description={description}
26
publishDate={publishDate}
27
onShareClick={onShareClick} />
28
</Areas.Content>
29
</>
30
)}
31
</Composition>
32
)
Copied!
components/ArtistCard/ArtistContent.jsx
1
import React from 'react'
2
import { Composition } from 'atomic-layout'
3
4
const areasMobile = `
5
meta
6
actions
7
text
8
`
9
10
const areasTablet = `
11
meta actions
12
text text
13
`
14
15
export const ArtistContent = ({ description, publishDate, onShareClick }) => (
16
<Composition
17
areas={areasMobile}
18
areasMd={areasTablet}
19
gap={10}
20
gapMd={20}>
21
{({ Meta, Actions, Text }) => (
22
<>
23
<Meta>
24
{publishDate}
25
</Meta>
26
<Actions>
27
<button onClick={onShareClick}>Share</button>
28
</Actions>
29
<Text>
30
{description}
31
</Text>
32
</>
33
)}
34
</Composition>
35
)
Copied!

Using areas templates

It is possible to describe the size of each column/row using a shorthand grid-template syntax.
    To specify a row size put its numeric value right after the row areas declaration.
    To specify a column size put a trailing slash (/) and provide each column's dimensions after it.
1
import React from 'react'
2
import { Composition } from 'atomic-layout'
3
4
const templateTablet = `
5
meta actions 250px
6
text text 1fr
7
/ 500px auto
8
`
9
10
export const ArtistContent = ({ description, publishDate, onShareClick }) => (
11
<Composition template={templateTablet}>
12
{(Areas) => (
13
<>
14
<Areas.Meta>{publishDate}</Areas.Meta>
15
<Areas.Actions>
16
<button onClick={onShareClick}>Share</button>
17
</Areas.Actions>
18
<Areas.Text>
19
{description}
20
</Areas.Text>
21
</>
22
)}
23
</Composition>
24
)
Copied!
Note that in order to use grid-template syntax you must provide the template string as a value of the template prop of the Composition component.
Last modified 1yr ago