Skip to main content

Carbon Design System in React.js - Part II

Guangzhou, China

Github Repository

Continuation of Part I - Using the IBM Carbon Design System in a React App.

Carbon Design System

IE11 Polyfills

Not sure if IE11 is still a thing, but some Carbon components require IE11 polyfills. I am going to install core-js and add these imports to the top of the root src/index.js:

npm install --save-dev core-js
import 'core-js/modules/es7.array.includes';
import 'core-js/modules/es6.array.fill';
import 'core-js/modules/es6.string.includes';
import 'core-js/modules/es6.string.trim';
import 'core-js/modules/es7.object.values';

Install Grid

In our last step we added our styles, component and icon packages. Now that we’re building the pages with grid, we need to install one more Carbon package:

npm install @carbon/grid@10.17.0

In src/index.scss, we need to configure our grid to use 16 columns instead of the default 12 columns. The feature flag needs to come before the Carbon styles.scss import:

$feature-flags: (
  grid-columns-16: true,
);

Add Landing Page Grid

Let’s add our grid elements to src/content/LandingPage/LandingPage.js.

In order to use the grid, we need to wrap everything in a <div className="bx--grid">. I can continue to make rows by adding a <div className="bx--row"> inside the grid, as well as make columns within those rows by adding <div className="bx--col-[breakpoint]-[size]">.

Our column sizes are specified by the number of columns they’ll be spanning. If we use bx--col-lg-4, it means it’ll span 4 of the 16 columns. If we use bx--col-lg-8 it means it’ll span 8 of the 16 columns, and so on.

return (
  <div className="bx--grid bx--grid--full-width landing-page">
    <div className="bx--row landing-page__banner">
      <div className="bx--col-lg-16">1</div>
    </div>
    <div className="bx--row landing-page__r2">
      <div className="bx--col-md-4 bx--col-lg-7">7/16</div>
      <div className="bx--col-md-4 bx--offset-lg-1 bx--col-lg-8">8/16</div>
    </div>
    <div className="bx--row landing-page__r3">
      <div className="bx--col-md-4 bx--col-lg-4">1/4</div>
      <div className="bx--col-md-4 bx--col-lg-4">1/4</div>
      <div className="bx--col-md-4 bx--col-lg-4">1/4</div>
      <div className="bx--col-md-4 bx--col-lg-4">1/4</div>
    </div>
  </div>
);

I added a class of bx--grid--full-width to the grid container since our rows need to expand the whole page without any margins. I also added some custom classes like landing-page, landing-page__banner, landing-page__r2, etc., which I will use later.

Also, take notice of the second row. The tab content only covers 7 columns at this large viewport to prevent overly-large line lengths, so we needed to add a 1 column offset bx--offset-lg-1 to second column to fill the full 16 columns in the grid. Then, both of those columns have bx--col-md-4 classes so they are of equal width at medium-sized viewports.

Building Landing Page

First Row - Breadcrumbs

In our first row we’ll need a BreadCrumb component. First, let’s import the components we need to src/content/LandingPage/LandingPage.js:

import { Breadcrumb, BreadcrumbItem } from 'carbon-components-react';

We can now add our component to the first row, along with a header, like so:

<div className="bx--row landing-page__banner">
  <div className="bx--col-lg-16">
    <Breadcrumb noTrailingSlash>
      <BreadcrumbItem>
        <a href="/">Introduction</a>
      </BreadcrumbItem>
    </Breadcrumb>
    <h1 className="landing-page__heading">INSTAR Carbon</h1>
  </div>
</div>

Second Row - Tabs

In our second row we’ll need Tabs and Button components. We’ll update the carbon-components-react import in src/content/LandingPage/LandingPage.js to:

import {
  Breadcrumb,
  BreadcrumbItem,
  Button,
  Tabs,
  Tab,
} from 'carbon-components-react';

Before we can render the tabs, we need to add some props for the component after the import in src/content/LandingPage/LandingPage.js. These example props came from the React Tabs Story in Storybook:

const props = {
  tabs: {
    selected: 0,
    role: 'navigation',
  },
  tab: {
    role: 'presentation',
    tabIndex: 0,
  },
};

Modify the second row to use the Tab component:

<div className="bx--row landing-page__r2">
  <div className="bx--col bx--no-gutter">
    <Tabs {...props.tabs}>
      <Tab {...props.tab} label="Hello World!">
        <div className="bx--grid bx--grid--no-gutter bx--grid--full-width">
          <div className="bx--row landing-page__tab-content">
            <div className="bx--col-md-4 bx--col-lg-7">
              Consectetur adipisicing elit. Eveniet eos repellendus aspernatur molestias autem sed soluta voluptate.
            </div>
            <div className="bx--col-md-4 bx--offset-lg-1 bx--col-lg-8">
              Voluptatibus numquam placeat dicta, delectus commodi iure, quam, distinctio enim consequatur repudiandae autem!
            </div>
          </div>
        </div>
      </Tab>
      <Tab {...props.tab} label="Contact">
        <div className="bx--grid bx--grid--no-gutter bx--grid--full-width">
          <div className="bx--row landing-page__tab-content">
            <div className="bx--col-lg-16">
              Lorem ipsum dolor sit amet consectetur adipisicing elit. Iusto quas in quasi, quisquam reiciendis repellendus natus fugit? Voluptatibus numquam placeat dicta, delectus commodi iure, quam, distinctio enim consequatur repudiandae autem!
            </div>
          </div>
        </div>
      </Tab>
      <Tab {...props.tab} label="More">
        <div className="bx--grid bx--grid--no-gutter bx--grid--full-width">
          <div className="bx--row landing-page__tab-content">
            <div className="bx--col-lg-16">
              Lorem ipsum, dolor sit amet consectetur adipisicing elit. Magni, inventore error officiis suscipit eos doloribus quam quidem, sapiente voluptas repellendus debitis iusto rem voluptatum cumque facilis, modi excepturi minus officia?
            </div>
          </div>
        </div>
      </Tab>
    </Tabs>
  </div>
</div>

Next, we’ll need to add some styling overrides to move the tabs to the right on large viewports. Create a file _overrides.scss in src/content/LandingPage with this declaration block.

.landing-page__r2 .bx--tabs--scrollable {
  transform: translateZ(0);
  justify-content: flex-end;
}
.landing-page__r2 .bx--tab-content {
  padding: 0;
}

Then in src/content/LandingPage/_landing-page.scss add this import at the top of the file:

@import './overrides.scss';

We can now add our images and text for each column in the Hello World! tab in src/content/LandingPage/LandingPage.js:

<Tab {...props.tab} label="Hello World!">
  <div className="bx--grid bx--grid--no-gutter bx--grid--full-width">
    <div className="bx--row landing-page__tab-content">
      <div className="bx--col-md-4 bx--col-lg-7">
        <h2 className="landing-page__subheading">
          What is Carbon?
        </h2>
        <p className="landing-page__p">
          Lorem ipsum, dolor sit amet consectetur adipisicing elit. Magni,
          inventore error officiis suscipit eos doloribus quam quidem,
          sapiente voluptas repellendus debitis iusto rem voluptatum cumque
          facilis, modi excepturi minus officia?
        </p>
        <Button>Learn more</Button>
      </div>
      <div className="bx--col-md-4 bx--offset-lg-1 bx--col-lg-8">
        <img
          className="landing-page__illo"
          src={`${process.env.PUBLIC_URL}/tab-illo.png`}
          alt="Carbon illustration"
        />
      </div>
    </div>
  </div>
</Tab>

Now let’s set the image size in src/content/LandingPage/_landing-page.scss:

.landing-page__illo {
  max-width: 100%;
}

Third Row - Header

The third row will be created later, so I’ll just add the headers for now src/content/LandingPage/LandingPage.js:

<div className="bx--row landing-page__r3">
  <div className="bx--col-md-4 bx--col-lg-4">
    <h3 className="landing-page__label">The Principles</h3>
  </div>
  <div className="bx--col-md-4 bx--col-lg-4">Carbon is Open</div>
  <div className="bx--col-md-4 bx--col-lg-4">Carbon is Modular</div>
  <div className="bx--col-md-4 bx--col-lg-4">Carbon is Consistent</div>
</div>