# First composition

Let's create our first composition. With Atomic Layout a UI composition is physical and you can render it as a React component called `<Composition/>`. Any layout piece is a combination of its counterparts, whether it's an entire page or a small button. You can apply this principle throughout the entire application and remain consistent in the way your components are declared.

**Consider the following UI element as our end goal:**

![Mobile design of the UI element.](https://701778105-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LDfdP5_KiHky6KSny85%2F-LlApTa5piPIeOJ7Y2OL%2F-LlB2rRi_sSODSuvWVw-%2Fdocs-getting-started-mobile.svg?alt=media\&token=91a14a21-5da0-4dde-b9c3-587361c57f81)

Following the best practices, we are going to start from mobile design and gradually move upward bigger screens.

## Creating a component

To start, let's create a new `Album` component that will represent our UI element.

{% code title="src/components/Album.js" %}

```jsx
import React from 'react'

export const Album = () => (
  <p>Nothing unusual yet</p>
)
```

{% endcode %}

## Composition

Next step, let's import the `Composition` components from the `atomic-layout` package at the top of your `Album` file:

{% code title="src/components/Album.js" %}

```jsx
import React from 'react'
import { Composition } from 'atomic-layout'
```

{% endcode %}

When describing a layout composition we can split our UI element in to pieces, or *areas*. Looking at our design, we could have the following areas:

![](https://701778105-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LDfdP5_KiHky6KSny85%2F-LlLwtW3U7U-01j6kmJf%2F-LlM0B70z9tGrfQgqdlR%2Fdocs-getting-started-areas.svg?alt=media\&token=eba69d95-88c5-471d-9e72-1f6f16ce0ead)

Although there are no strict rules regarding areas breakdown, try for area names to be meaningful in their domain. For example, favor area names like "thumbnail" or "content" over "top" or "bottom". This is especially useful when dealing with responsive layouts, as the position of an area may change. Having "top" area on the bottom right is rather ridiculous.

> ### Composition areas are verbal representation of layout areas, sensitive to their position in space and relation to each other.

Once we are happy with the areas names, we need to write them down. We are going to create a variable `areasMobile` that will hold a description of our areas on mobile screens.

{% code title="src/components/Album.js" %}

```jsx
// Template string literal helps to preserve the vertical relation
// of areas. Below, we've described three areas one by one,
// just as they appear on the design.
const areasMobile = `
  thumbnail
  content
  actions
`
```

{% endcode %}

On its own the `areasMobile` variable is just a string. In order for it to be used as a blueprint for a layout composition, we need to pass it as a value to the `areas` prop of the `Composition` component:

{% code title="src/components/Album.js" %}

```jsx
export const Album = () => (
  <Composition areas={areasMobile}>
    <p>Still nothing extraordinary</p>
  </Composition>
)
```

{% endcode %}

If a Composition component accepts areas it returns React components generated based on passed areas. Those components are available in the children render function as arguments:

{% code title="src/components/Album.js" %}

```jsx
export const Album = () => (
  <Composition areas={areasMobile}>
    /* React components based on "areasMobile" areas */
    {(Areas) => (
      <> // <- notice the React.Fragment wrapper
        <Areas.Thumbnail>Our thumbnail</Areas.Thumbnail>
        <Areas.Content>Content</Areas.Content>
        <Areas.Actions>Call to action</Areas.Actions>
      </>
    )}
  </Composition>
)
```

{% endcode %}

> Pay attention that all children (area components) are wrapped in `React.Fragment` (`<></>`). This is necessary because CSS Grid currently affects only direct children, so must make sure area components are direct children of the `Composition`.

Now we can render other components inside those area component to make up the desired appearance. This is an example of how this would look like:

{% code title="src/components/Album.js" %}

```jsx
export const Album = ({ title, imageUrl, releaseYear, artistName }) => (
  <Composition areas={areasMobile}>
    {(Areas) => (
      <>
        <Areas.Thumbnail>
          <img src={imageUrl} alt={title} />
        </Areas.Thumbnail>
        <Areas.Content>
          <h3>{title}</h3>
          <p>{artistName} • {releaseYear}</p>
        </Areas.Content>
        <Areas.Actions>
          <button>Buy</button>
        </Areas.Actions>
      </>
    )}
  </Composition>
)
```

{% endcode %}

{% hint style="warning" %}
Styling visual appearance of children UI elements, such as image or button, is not a part of this tutorial, because it's not the responsibility of Atomic Layout. Please refer to the complete example (live sandbox) at the bottom of this page for styling references.
{% endhint %}

## Areas relation

Our areas template string describes a spacial relation of areas. However, to specify things like an area's dimensions, or spacing between the areas, we may use additional CSS properties.

For example, to space out the areas we can use the `gap` prop (that aliases `grid-gap` CSS property).

{% code title="src/components/Album.js" %}

```jsx
export const Album = () => (
  <Composition areas={areasMobile} gap={10}>
    {(Areas) => (
      /* Same areas here... */
    )}
  </Composition>
)
```

{% endcode %}

> Prop `gap={10}` applies `grid-gap: 10px;` in the generated styles.

{% hint style="success" %}
Read about [**CSS Grid**](https://developer.mozilla.org/en-US/docs/Web/CSS/grid) to know how to describe created compositions (CSS Grid containers). You are going to use this knowledge a lot when working with the library.
{% endhint %}

## Summary

In this section we have learned:

* How to break down UI element to composition areas;
* How to use Composition component;
* How to control relation between composition areas;

### Live example

{% embed url="<https://codesandbox.io/embed/getting-started-first-composition-36et8?fontsize=14&hidenavigation=1&module=%2Fsrc%2Fsteps%2Ffirst-composition%2Findex.js&moduleview=1&theme=light>" %}
Getting Started sandbox
{% endembed %}
