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.
Renders composition with display: inline-grid
.
Usage
Define templates
Composition begins by defining a template string that consists of layout (grid) areas.
Copy const areasMobile = `
logo
menu
`
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.
Copy const areasTablet = `
logo menu
search search
`
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:
Copy < Composition
areas = {areasMobile}
areasMd = {areasTablet}>
{(Areas) => (
<>
< Areas.Logo >...</ Areas.Logo >
< Areas.Search >...</ Areas.Search >
< Areas.Menu >...</ Areas.Menu >
</>
)}
</ Composition >
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:
Copy < Composition
areas = {areasMobile}
areasMd = {areasTablet}
templateCols = "1fr auto"
templateColsMd = "1fr 1fr" />
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.
Copy import React from 'react'
import { Composition } from 'atomic-layout'
export const Header = () => (
< Composition templateCols = "repeat(3, 1fr)" >
< Logo />
< Menu />
< Actions />
</ Composition >
)
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.
page Box Simple composition
src/components/ArtistCard/index.jsx
Copy import React from 'react'
import { Composition } from 'atomic-layout'
const areasMobile = `
thumbnail
heading
content
`
const areasDesktop = `
thumbnail heading
thumbnail content
`
export const ArtistCard = ({ title , imageUrl , description }) => (
< Composition
areas = {areasMobile}
areasMd = {areasDesktop}
gap = { 10 }
gapMd = { 20 }
padding = { 10 }>
{(Areas) => (
<>
< Areas.Thumbnail >
< img src = {imageUrl} alt = {title} />
</ Areas.Thumbail >
< Areas.Heading >
< h3 >{title}</ h3 >
</ Areas.Heading >
< Areas.Content >
< p >{description}</ p >
</ Areas.Content >
</>
)}
</ Composition >
)
Nested composition
components/ArtistCard/index.jsx
Copy import React from 'react'
import { Composition } from 'atomic-layout'
import ArtistContent from './ArtistContent'
const areasMobile = `
thumbnail
content
`
export const ArtistCard = ({
title ,
description ,
publishDate ,
imageUrl ,
onShareClick
}) => (
< Composition areas = {areasMobile}>
{(Areas) => (
<>
< Areas.Thumbnail >
< img src = {imageUrl} alt = {title} />
</ Areas.Thumbnail >
< Areas.Content >
< ArtistContent
description = {description}
publishDate = {publishDate}
onShareClick = {onShareClick} />
</ Areas.Content >
</>
)}
</ Composition >
)
components/ArtistCard/ArtistContent.jsx
Copy import React from 'react'
import { Composition } from 'atomic-layout'
const areasMobile = `
meta
actions
text
`
const areasTablet = `
meta actions
text text
`
export const ArtistContent = ({ description , publishDate , onShareClick }) => (
< Composition
areas = {areasMobile}
areasMd = {areasTablet}
gap = { 10 }
gapMd = { 20 }>
{({ Meta , Actions , Text }) => (
<>
< Meta >
{publishDate}
</ Meta >
< Actions >
< button onClick = {onShareClick}>Share</ button >
</ Actions >
< Text >
{description}
</ Text >
</>
)}
</ Composition >
)
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.
Copy import React from 'react'
import { Composition } from 'atomic-layout'
const templateTablet = `
meta actions 250px
text text 1fr
/ 500px auto
`
export const ArtistContent = ({ description , publishDate , onShareClick }) => (
< Composition template = {templateTablet}>
{(Areas) => (
<>
< Areas.Meta >{publishDate}</ Areas.Meta >
< Areas.Actions >
< button onClick = {onShareClick}>Share</ button >
</ Areas.Actions >
< Areas.Text >
{description}
</ Areas.Text >
</>
)}
</ Composition >
)
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.