Advanced Components
  • Welcome
  • Start here
    • Setup
    • Dependencies
  • Getting Started
    • Front-end tooling
    • Create a new D9 theme
    • Component Architecture
    • Drupal Best Practices
    • Drupal Attributes
    • Twig Blocks
  • Basic Components
    • Global styles
    • Adding webfonts
    • Heading Component
      • Improving the Heading
    • Button Component
  • A component's lifecycle
    • Hero Component
    • Include statements
    • Drupal prep
    • Drupal entities
    • Homepage content type
    • View modes
    • Add Hero to homepage
    • Drupal cache & twig debugging
    • Twig template suggestions
    • Getting field values
    • Integrating the Hero
    • Drupal Libraries
    • Hero Image styles
  • Card component
    • Card Component
    • Component Variants
    • Card Variant
    • Author component
  • Drupal site building
    • Blog articles
    • View modes
    • Drupal Views
    • Author
    • Generate content
    • Adding Blog Lists to the Homepage
  • Drupal Integrations
    • Integrating the Card
      • Taxonomy terms
    • Integrating the Card Wide
    • Author integration
    • From our blog
    • Integrating From our blog
    • Featured Content
    • Integrating Featured Content
    • Blog image styles
    • Blog detail page
  • Extras
    • Image Styles
    • Navigation
  • Resources
    • Resources
Powered by GitBook
On this page
  • Exercise: Build the Hero component
  • Component's stock content
  • Component's Markup
  • Component's styles
  • Compiling the code

Was this helpful?

  1. A component's lifecycle

Hero Component

PreviousButton ComponentNextInclude statements

Last updated 3 years ago

Was this helpful?

The Hero component is a more complex component because it contains more fields, logic and it also makes use of previously built components. With the Hero we will reuse other components by using twig's statements. More on this later.

Whether you are building simple or complex components, the process for getting started is the same; create files for data, markup and styles. Let's do this with the Hero component.

First let's take a look at how this component looks so we can identify the different data fields we need.

Based on the design above, we need the following fields:

  • title or heading

  • image

  • call to action (CTA)

Exercise: Build the Hero component

Component's stock content

  1. Inside components create a new folder called hero

  2. Inside the hero folder create a new file called hero.json

  3. Inside hero.json add the following code:

{
  "image": "<img src='https://source.unsplash.com/DOoYFgTQWfs/1900x700' alt='Books on computer' />",
  "heading": {
    "heading_level": "1",
    "modifier": "hero__title",
    "title": "Today's trends",
    "url": ""
  },
  "cta": {
    "text": "Get started",
    "url": "#",
    "modifier": "hero__cta"
  },
  "modifier": ""
}

Just as we did with the Heading component, we are using JSON to define the component's fields and add stock/dummy content to the component. Our goal here is to reuse previously built components by nesting them into the hero to avoid code duplicate and improve maintenance of component by having a single source of code.

Some things to notice:

  • We created data objects for heading and cta. Although this is not required, doing this helps to organize fields and their properties as well as it simplifies the component nesting process in Twig. More on this shortly

  • We added a modifier key with an empty value. This will come in handy when we need to pass custom CSS classes to component to style them.

Component's Markup

Now let's write some HTML for the component.

  1. Inside the hero folder create a new file called hero.twig

  2. Inside hero.twig add the following code:

<section class="hero{{ modifier ? ' ' ~ modifier }}
  {{- attributes ? ' ' ~ attributes.class -}}"
  {{- attributes ? attributes|without(class) -}}>
  {{ title_prefix }}
  {{ title_suffix }}
  

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

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

</div>

  <div class="hero__content">
    

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

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

</div>

    

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

      {%
        include '@training_theme/button/button.twig' with {
          "button": cta
        } only
      %}
    

</div>

  </div>
</section>

Some things to notice:

  • In line 1, in addition to the component's class of hero we are writing a conditional statement to determine if there is a value being passed for the modifier ({{ modifier ? ' ' ~ modifier }}), and if so, we are printing it as an additional CSS class.

  • Still in line 1, we are preparing this component for when we integrate it with Drupal by assigning a placeholder for any Drupal attributes that may be available. We will make use of attributes later in the process.

  • For each field we want to print, we first check if there is content to print using a Twig conditional statement (if). This is a good practice so we don't print empty HTML tags.

  • Notice how every field and div uses a css class that starts with hero__*. Defining relationships between the parent elements and child elements by using the same namespace (hero__), makes it easier to identify elements when inspecting code as well as finding those elements in our project.

  • Lastly, and super important, we make use of Twig's include statement to include or nest the Heading and Button components into the Hero. This is extremely powerful and we will be talking more about it later. Biggest benefit of include statements is that we can reuse other components to avoid duplicating code.

Component's styles

  1. Inside the hero folder create a new file called hero.scss

  2. Inside hero.scss add this code:

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

.hero {
  @include component-spacing;
  @include image-crop (320px);
  margin-bottom: 0;

  @media screen and (min-width: $bp-sm) {
    height: 400px;
  }

  @media screen and (min-width: $bp-md) {
    height: 600px;
  }

  @media screen and (min-width: $bp-xl) {
    height: 700px;
  }

  // Styles heading when inside the hero.
  .heading {
    color: $color-navy-blue;
    font-size: 6rem;
    font-weight: 900;
    margin-bottom: 10px;
    text-transform: uppercase;

    @media screen and (min-width: $bp-md) {
      font-size: 8rem;
      margin-bottom: 25px;
    }

    @media screen and (min-width: $bp-lg) {
      font-size: 10rem;
      margin-bottom: 25px;
    }

    @media screen and (min-width: $bp-xl) {
      margin-bottom: 50px;
      font-size: 12rem;
    }
  }
}

.hero__content {
  @include center-align(absolute);
  text-align: center;
  width: 100%;
}

.hero__media {

  // Fixes drupal bug with position property when
  // rendering image in drupal.
  .contextual-region {
    position: unset;
  }
}

We'll refine these styles later on.

Compiling the code

If Pattern Lab is running you should see the Hero component in Pattern Lab under the Component menu item. Otherwise run the commands below:

npm run watch

TIP: Since we created a whole new component; if you had the watch task running, you may need to stop it by pressing Ctrl + C on your keyboard, and run npm run build. This will ensure the new component will be generated and all related code will be compiled.

We're starting off with a <section> HTML5 tag. Learn more about the tag. This is the parent selector of the component and therefore assigned the CSS class of hero, which also becomes the namespace for this component. This namespace helps with CSS scope to ensure our styles are unique to this and this component only.

In your browser of choice open the following URL: . This will open Pattern Lab where you can find the Hero component under components.

section
http://localhost:3000
include
Hero component