# Card Component

A component that will introduce us to a more useful technique for working with components is the image you see below. A Card component is a great way to display all sorts of content (news, blog posts, events, etc.), and you will see it in many websites nowadays. The card is not typically displayed on its own, although sometimes it is, but its most common use is as a collection of content. For example, we could use a collection of cards to display latest blog posts or upcoming events. In this training we will use the card component to build two content lists; Featured Content, and Blog Content.

![Example of a Card component](https://2922542435-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M1l4SrAN2BCmBBrGH8v%2Fuploads%2Fgit-blob-9ddabf93af85033d66d5927e64ac41a76d61c132%2Fcard.png?alt=media)

Although we could build the content list components already as a collection of content, a better approach is to first build a single instance of a card component that then we can reuse over and over. Having a single card component available makes it possible to even build other types of content collections.

## Exercise: Card component

As we've did with the Hero component, one of the first things we need to define are the data fields that makeup the component. If you look at the image above, a single Card has the following data fields:

* image
* title (link to full article)
* date
* body
* & tags

Now that we have identified the fields our card component needs, let's start building it.

### Component's stock content

1. Inside `src/patterns/components` create a new folder called **card**
2. Inside the *card* folder create a new file called **card.json**
3. Inside *card.json* add the following code:

{% tabs %}
{% tab title="card.json" %}

```yaml
{
  "image": "<img src='https://source.unsplash.com/6VhPY27jdps/640x360' alt='Cups of coffee' />",
  "heading": {
    "heading_level": "2",
    "modifier": "card__title",
    "title": "Staying sane in times of chaos",
    "url": "#"
  },
  "date": "March 16 2020",
  "body_text": "Curabitur blandit tempus porttitor. Vestibulum id ligula porta felis euismod semper. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.",
  "tags": [
    {
      "name": "Health",
      "url": "#"
    },
    {
      "name": "Friend",
      "url": "#"
    },
    {
      "name": "Life",
      "url": "#"
    }
  ],
  "modifier": ""
}
```

{% endtab %}
{% endtabs %}

By now we should be well familiar with the fields structure above. The one field type we probably have not seen until now is an array. In the code above we are declaring the tags as an array of items. Each tag item inside the array has a `text` and `url` keys so they can become links to tag-driven pages on our site.

### Component's markup

1. Inside the *card* folder create a new file called **card.twig**
2. Inside *card.twig* add the following code:

{% tabs %}
{% tab title="card.twig" %}

```php
{{ attach_library('training_theme/card') }}

<article class="card{{ modifier ? ' ' ~ modifier }}{{- attributes ? ' ' ~ attributes.class -}}"
  {{- attributes ? attributes|without(class) -}}>

  

<div data-gb-custom-block data-tag="if">

    <div class="card__media">
      {{ image }}
    </div>
  

</div>

  <div class="card__content">
    

<div data-gb-custom-block data-tag="if">

      {{ title_prefix }}
      {%
        include '@training_theme/heading/heading.twig' with {
          heading: heading
        } only
      %}
      {{ title_suffix }}
    

</div>

    

<div data-gb-custom-block data-tag="if">

      <div class="eyebrow card__date">
        {{ date }}
      </div>
    

</div>

    

<div data-gb-custom-block data-tag="if">

      <div class="card__body">
        {{ body_text }}
      </div>
    

</div>

    

<div data-gb-custom-block data-tag="if">

      <ul class="tags">
        

<div data-gb-custom-block data-tag="for">

          <li class="tag__item">
            <a href="{{ item.url }}" class="tag__link">
              {{ item.name }}
            </a>
          </li>
        

</div>

      </ul>
    

</div>

  </div>
</article>
```

{% endtab %}
{% endtabs %}

* Just as we did with the Hero, we are including the `attributes` placeholder so when we integrate the card with Drupal the attributes Drupal provides can be available in our card.
* Once again we are making use of the Heading component by using a Twig include statement.
* With the tags we loop through the `tags` array and then add each tag item as a list item in an unordered list.

{% hint style="warning" %}
Don't forget to create and attach the Card's library.
{% endhint %}

### Component styles

1. Inside the *card* folder create a new file called **card.scss**
2. Inside *card.scss* add the following code:

{% tabs %}
{% tab title="card.scss" %}

```css
// Import site utilities
@import '../../global/utils/init';

.card {
  background-color: $color-white;
  box-shadow: 0 10px 15px -3px rgba($color-black, 0.1), 0 4px 6px -2px rgba($color-black, 0.05);
  box-sizing: border-box;
  display: flex;
  flex: 0 0 auto;
  flex-direction: column;
  max-width: 320px;
  position: relative;

  @media screen and (min-width: $bp-md) {
    flex: 0 0 45%;
  }

  img {
    display: block;
    width: 100%;
  }

  .card__content {
    padding: 10px 20px 20px;
  }

  // ========== Card wide styles=========
  &.card--wide {
    border: 1px solid darken($color-gray-light, 10%);
    box-shadow: none;
    flex-direction: column;

    // Adds blue corner ship to card wide.
    &::before {
      border-right: 70px solid transparent;
      border-top: 70px solid $color-navy-blue;
      display: block;
      content: '';
      height: 0;
      left: -1px;
      position: absolute;
      top: -1px;
      width: 0;
      z-index: $zi-lowest;
    }

    // Positions date in 45 degrees over blue chip.
    .card__featured--date {
      color: $color-white;
      font-size: 1.2rem;
      font-weight: bold;
      left: 0;
      line-height: 1;
      position: absolute;
      text-transform: uppercase;
      top: 18px;
      transform: rotate(-45deg);
      z-index: $zi-lowest;
    }

    // Changes card layout on larger screens.
    @media screen and (min-width: $bp-sm) {
      flex-direction: row;
      max-width: 720px;

      .card__content {
        flex: 0 0 70%;

        @include breakpoint($bp-sm) {
          display: flex;
          flex-direction: column;
          flex-grow: 1;
        }
      }

      img {
        max-width: 100%;
      }
    }

    .card__media {

      @include breakpoint($bp-sm) {
        flex: 0 0 30%;
      }
    }
  }

  .eyebrow {
    border-bottom: 1px solid $color-gray-med;
    font-size: 1.3rem;
    letter-spacing: 2px;
    text-transform: uppercase;
    padding-bottom: 8px;
  }

  .author {
    margin-top: auto;
    justify-content: flex-end;
  }
}

.card__body {
  margin-bottom: 20px;
}

.card__title {
  font-size: 2.4rem;
  font-weight: 600;
  margin: 0;
}
```

{% endtab %}
{% endtabs %}

* We'll get into the styles above in more detail later on.

### Compiling the code

Now that the card component is done, let's compile the code so we can see it in Pattern Lab. If the watch task is running you should be able to see the card component in Pattern Lab, otherwise follow these steps:

While in your theme's root directory, run the following commands in your command line and press **Return**

`npm run build`

`npm run watch`

In your browser of choice open the following URL: <http://localhost:3000>. This will open Pattern Lab where you can find the Card component under components.

### Accessing Pattern Lab from within Drupal

When working with Pattern Lab locally it makes sense to use <http://localhost:3000> to view your work. However, if you are viewing your project from a server during development, or want to show your work and progress to a stakeholder or client, this approach will not work. Luckily for us, we can access Pattern Lab using Drupal's URL as follows:

`/themes/custom/training_theme/patternlab/index.html`

Two things to keep in mind with the path above:

1. The path above is appended to your Drupal's base URL. For example, if your Drupal's address is *<https://dev.pantheon.io>*, the full URL would become **<https://dev.pantheon.io/themes/custom/training\\_theme/patternlab/index.html>**
2. Replace `training_theme` with your project's theme name if your theme name is different.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://mariohernandez.gitbook.io/components/card-component/card.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
