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>