{"componentChunkName":"component---src-pages-tutorial-react-step-4-mdx","path":"/tutorial/react/step-4/","result":{"pageContext":{"frontmatter":{"title":"4. Creating components","description":"Welcome to Carbon! This tutorial will guide you in creating a React app with the Carbon Design System.","tabs":["Overview","Step 1","Step 2","Step 3","Step 4","Step 5","Wrapping up"]},"relativePagePath":"/tutorial/react/step-4.mdx","titleType":"prepend","MdxNode":{"id":"08d32e0b-8481-5631-b3aa-b80c3adcf197","children":[],"parent":"02eb342a-658b-5334-964d-9c917191eed6","internal":{"content":"---\ntitle: 4. Creating components\ndescription: Welcome to Carbon! This tutorial will guide you in creating a React app with the Carbon Design System.\ntabs:\n  ['Overview', 'Step 1', 'Step 2', 'Step 3', 'Step 4', 'Step 5', 'Wrapping up']\n---\n\nimport Preview from 'components/Preview';\n\n<PageDescription>\n\nWith two pages comprised entirely of Carbon components, let's revisit the\nlanding page and build a couple components of our own by using Carbon icons\nand tokens.\n\n</PageDescription>\n\n<AnchorLinks>\n\n<AnchorLink>Fork, clone and branch</AnchorLink>\n<AnchorLink>Review design</AnchorLink>\n<AnchorLink>Create components</AnchorLink>\n<AnchorLink>Use components</AnchorLink>\n<AnchorLink>Add styling</AnchorLink>\n<AnchorLink>Check accessibility</AnchorLink>\n<AnchorLink>Submit pull request</AnchorLink>\n\n</AnchorLinks>\n\n## Preview\n\nCarbon provides a solid foundation for building web applications through its color palette, layout, spacing, type, as well as common building blocks in the form of components. So far, we've only used Carbon components to build out two pages.\n\nNext, we're going to use Carbon assets to build application-specific components. We'll do so by including accessibility and responsive considerations all throughout.\n\nA [preview](https://react-step-5--carbon-tutorial.netlify.com) of what you'll build (see bottom of page):\n\n<Preview\n  height=\"400\"\n  title=\"Carbon Tutorial Step 4\"\n  src=\"https://react-step-5--carbon-tutorial.netlify.com\"\n  frameborder=\"no\"\n  allowtransparency=\"true\"\n  allowfullscreen=\"true\"\n  class=\"bx--iframe bx--iframe--border\"\n/>\n\n## Fork, clone and branch\n\nThis tutorial has an accompanying GitHub repository called [carbon-tutorial](https://github.com/carbon-design-system/carbon-tutorial) that we'll use as a starting point for each step. If you haven't forked and cloned that repository yet, and haven't added the upstream remote, go ahead and do so by following the [step 1 instructions](/tutorial/react/step-1#fork-clone--branch).\n\n### Branch\n\nWith your repository all set up, let's check out the branch for this tutorial step's starting point.\n\n```bash\n$ git fetch upstream\n$ git checkout -b react-step-4 upstream/react-step-4\n```\n\n_Note: This builds on top of step 3, but be sure to check out the upstream step 4 branch because it includes the static assets required to get through this step._\n\n### Build and start app\n\nInstall the app's dependencies (in case you're starting fresh in your current directory and not continuing from the previous step):\n\n```bash\n$ yarn\n```\n\nThen, start the app:\n\n```bash\n$ yarn start\n```\n\nYou should see something similar to where the [previous step](/tutorial/react/step-3) left off.\n\n## Review design\n\nHere's what we're building – an informational section that has a heading and three subheadings. Each subheading has accompanying copy and a pictogram. We'll assume that this informational section is used elsewhere on the site, meaning it's a great opportunity to build it as a resusable component. As for naming, we'll call it an `InfoSection` with three `InfoCard`s as children.\n\n![Info section layout](../shared/step-4/images/info-layout.png)\n\n<Caption>Info section layout</Caption>\n\n## Create components\n\nFirst we need files for the components, so create an `Info` folder in `src/components`. Even though we're building multiple components, their names all start with `Info`, so it makes sense to have them share one folder in components. Create these files:\n\n### Add files\n\n```bash\nsrc/components/Info\n├──_info.scss\n├──index.js\n└──Info.js\n```\n\nImport `_info.scss` in `app.scss` after all of the `carbon-component` imports.\n\n```scss path=src/app.scss\n@import './components/Info/info.scss';\n```\n\nLike our other components, `index.js` will serve as an entrypoint. Since `Info.js` will export mutliple components, we'll use the `*` wildcard in the entrypoint export.\n\n```javascript path=src/components/Info/index.js\nexport * from './Info';\n```\n\n### InfoSection component\n\nLet's create the parent component that includes the \"The Principles\" heading. That markup currently looks like this in `LandingPage.js`:\n\n```html path=src/content/LandingPage/LandingPage.js\n<div className=\"bx--row landing-page__r3\">\n  <div className=\"bx--col-md-4 bx--col-lg-4\">\n    <h3 className=\"landing-page__label\">The Principles</h3>\n  </div>\n  <div className=\"bx--col-md-4 bx--col-lg-4\">Carbon is Open</div>\n  <div className=\"bx--col-md-4 bx--col-lg-4\">Carbon is Modular</div>\n  <div className=\"bx--col-md-4 bx--col-lg-4\">Carbon is Consistent</div>\n</div>\n```\n\nWe want to do a few things when abstracting it to a component. First, we only want Carbon (`bx--`) and this component's class names; we don't want to include `landing-page__r3` as that's specific to the landing page. For that we'll use React `props` so we can pass in and use `props.className`.\n\nWe'll also:\n\n- Add component class names like `info-section` and `info-section__heading`\n- Semantically use `<section>` instead of `<div>`\n- Update the grid columns to match the design\n- Replace `The Principles` with `{props.heading}`\n- Replace columns 2 - 4 with `{props.children}`\n\nUsing `props` we can render any heading and any number of children components (`InfoCard` that we'll build soon.)\n\n```javascript path=src/components/Info/Info.js\nimport React from 'react';\n\nconst InfoSection = props => (\n  <section className={`bx--row ${props.className} info-section`}>\n    <div className=\"bx--col-md-8 bx--col-lg-4 bx--col-xlg-3\">\n      <h3 className=\"info-section__heading\">{props.heading}</h3>\n    </div>\n    {props.children}\n  </section>\n);\n```\n\nAt this point let's add styling for the new class names that we just added.\n\n```scss path=src/components/Info/_info.scss\n.info-section__heading {\n  @include carbon--type-style('heading-01');\n}\n```\n\n### InfoCard component\n\nNext up we're going to build a component for columns 2 - 4, which currently looks like `<div className=\"bx--col-md-4 bx--col-lg-4\">Carbon is Open</div>`. At the bottom of `Info.js`, add:\n\n```javascript path=src/components/Info/Info.js\nconst InfoCard = props => {\n  return (\n    <article className=\"info-card bx--col-md-4 bx--col-lg-4 bx--col-xlg-3 bx--offset-xlg-1\">\n      <h4 className=\"info-card__heading\">{props.heading}</h4>\n      <p className=\"info-card__body\">{props.body}</p>\n      {props.icon}\n    </article>\n  );\n};\n\nexport { InfoSection, InfoCard };\n```\n\n_Note: Make sure to export the two components!_\n\nIn doing so, we:\n\n- Used the semantic `<article>` instead of `<div>`\n- Added `info-card` classes\n- Used `props` to render the heading, body copy, and icon\n- Set columns to match the grid\n\n_Note: At extra large viewports, we are using _`bx--col-xlg-3 bx--offset-xlg-1`_ so each column takes up 3 of the 16 grid columns, with a 1 column offset._\n\n## Use components\n\nNothing is styled yet, but with our components built let's put them to use. In `LandingPage.js`, import the components towards the top of the file.\n\n```javascript path=src/content/LandingPage/LandingPage.js\nimport { InfoSection, InfoCard } from '../../components/Info';\n```\n\nWhile we're at the top of `LandingPage.js`, import the icons that we'll need as well.\n\n```javascript path=src/content/LandingPage/LandingPage.js\nimport Globe32 from '@carbon/icons-react/lib/globe/32';\nimport PersonFavorite32 from '@carbon/icons-react/lib/person--favorite/32';\nimport Application32 from '@carbon/icons-react/lib/application/32';\n```\n\n_Note: You'll notice that these 32px icons aren't the pictograms as designed. The Carbon team is currently working on adding pictograms to the icons packages. Until then, we'll use the biggest SVGs._\n\nWith everything imported, replace the current:\n\n```html path=src/content/LandingPage/LandingPage.js\n<div className=\"bx--row landing-page__r3\">\n  <div className=\"bx--col-md-4 bx--col-lg-4\">\n    <h3 className=\"landing-page__label\">The Principles</h3>\n  </div>\n  <div className=\"bx--col-md-4 bx--col-lg-4\">Carbon is Open</div>\n  <div className=\"bx--col-md-4 bx--col-lg-4\">Carbon is Modular</div>\n  <div className=\"bx--col-md-4 bx--col-lg-4\">Carbon is Consistent</div>\n</div>\n```\n\nWith the new components:\n\n<!-- prettier-ignore-start -->\n```javascript path=src/content/LandingPage/LandingPage.js\n<InfoSection heading=\"The Principles\" className=\"landing-page__r3\">\n  <InfoCard\n    heading=\"Carbon is Open\"\n    body=\"It's a distributed effort, guided by the principles of the open-source movement. Carbon's users are also it's makers, and everyone is encouraged to contribute.\"\n    icon={<PersonFavorite32/>}\n  />\n  <InfoCard\n    heading=\"Carbon is Modular\"\n    body=\"Carbon's modularity ensures maximum flexibility in execution. It's components are designed to work seamlessly with each other, in whichever combination suits the needs of the user.\"\n    icon={<Application32/>}\n  />\n  <InfoCard\n    heading=\"Carbon is Consistent\"\n    body=\"Based on the comprehensive IBM Design Language, every element and component of Carbon was designed from the ground up to work elegantly together to ensure consistent, cohesive user experiences.\"\n    icon={<Globe32/>}\n  />\n</InfoSection>\n```\n<!-- prettier-ignore-end -->\n\n_Note: Now is a good time to resize your browser from phone to extra large viewport widths to see how the responsive grid is working before we add further styling._\n\n## Add styling\n\nHere's our design showing the spacing tokens that we need to add. We also need to set type style and borders.\n\n![Info section spacing](../shared/step-4/images/info-spacing.png)\n\n### Layout\n\nStarting with layout, add the following to `src/components/Info/_info.scss`.\n\n```scss path=src/components/Info/_info.scss\n.info-card {\n  margin-top: $spacing-09;\n  display: flex;\n  flex-direction: column;\n\n  svg {\n    margin-top: $spacing-09;\n  }\n\n  // top border in only small breakpoints to prevent overrides\n  @include carbon--breakpoint-down(md) {\n    &:not(:nth-child(2)) {\n      border-top: 1px solid $ui-03;\n      padding-top: $spacing-09;\n    }\n  }\n\n  // left border in just the 2nd column items\n  @include carbon--breakpoint(md) {\n    &:nth-child(odd) {\n      border-left: 1px solid $ui-03;\n    }\n  }\n\n  // left border in all items\n  @include carbon--breakpoint(lg) {\n    margin-top: 0;\n    border-left: 1px solid $ui-03;\n\n    svg {\n      margin-top: $layout-06;\n    }\n  }\n}\n```\n\nOnce you save, go ahead and resize your browser to see the responsive layout at the different breakpoints. Make sure to review these color and spacing tokens. There are also a few breakpoint mixins that may be new to you. The `@carbon/layout` [SassDoc](https://github.com/carbon-design-system/carbon/blob/master/packages/layout/docs/sass.md) is a great reference to see what all is available.\n\n### Type\n\nOur `InfoCard` headings look to be too small. We need to increase their font sizes according to the design spec with:\n\n```scss path=src/components/Info/_info.scss\n.info-card__heading {\n  @include carbon--type-style('productive-heading-03');\n}\n```\n\nAlso, the design has the last word in each subheading as bold. To accomplish that, add this helper function after the import in `Info.js`.\n\n```javascript path=src/components/Info/Info.js\n// Take in a phrase and separate the third word in an array\nfunction createArrayFromPhrase(phrase) {\n  const splitPhrase = phrase.split(' ');\n  const thirdWord = splitPhrase.pop();\n  return [splitPhrase.join(' '), thirdWord];\n}\n```\n\nThen, update `InfoCard` to use `createArrayFromPhrase`.\n\n```javascript path=src/components/Info/Info.js\nconst InfoCard = props => {\n  const splitHeading = createArrayFromPhrase(props.heading);\n\n  return (\n    <article className=\"info-card bx--col-md-4 bx--col-lg-4 bx--col-xlg-3 bx--offset-xlg-1\">\n      <h4 className=\"info-card__heading\">\n        {`${splitHeading[0]} `}\n        <strong>{splitHeading[1]}</strong>\n      </h4>\n      <p className=\"info-card__body\">{props.body}</p>\n      {props.icon}\n    </article>\n  );\n};\n```\n\nFinally, add the declaration block in `_info.scss` to set `InfoCard` body copy styles and to bottom-align the icons.\n\n```scss path=src/components/Info/_info.scss\n.info-card__body {\n  margin-top: $spacing-06;\n  flex-grow: 1; // fill space so icons are bottom aligned\n  @include type-style('body-long-01');\n\n  // prevent large line lengths between small and medium viewports\n  @include carbon--breakpoint-between(321px, md) {\n    max-width: 75%;\n  }\n}\n```\n\n## Check accessibility\n\nWe've added new markup and styles, so it's a good practice to check [DAP](https://www.ibm.com/able/dynamic-assessment-plug-in.html) and make sure our rendered markup is on the right track for accessibility.\n\nWith the browser extension installed, Chrome in this example, open Dev Tools and run DAP.\n\n![DAP violations](../shared/step-4/images/DAP-violations.png)\n\n<Caption>DAP violations</Caption>\n\nThat first violation is for the off-screen \"skip to content\" link. This link isn't shown and is used to assist screen reading, so the color contrast violation can be ignored.\n\nBut, those three other violations came from the `<article>` element used in new `InfoCard`. Since the `<article>` element requires a label, it seems like we may be using the wrong semantic element. A humble `<div>` will suffice.\n\nIn `Info.js`, replace the `<article>` opening and closing tags with `<div>` tags.\n\n## Submit pull request\n\nWe're going to submit a pull request to verify completion of this tutorial step.\n\n### Continuous integration (CI) check\n\nRun the CI check to make sure we're all set to submit a pull request.\n\n```bash\n$ yarn ci-check\n```\n\n_Note: Having issues running the CI check? [Step 1](</tutorial/react/step-1#continuous-integration-(ci)-check>) has troubleshooting notes that may help._\n\n### Git commit and push\n\nBefore we can create a pull request, stage and commit all of your changes:\n\n```bash\n$ git add --all && git commit -m \"feat(tutorial): complete step 4\"\n```\n\nThen, push to your repository:\n\n```bash\n$ git push origin react-step-4\n```\n\n_Note: Having issues pushing your changes? [Step 1](/tutorial/react/step-1#git-commit-and-push) has troubleshooting notes that may help._\n\n### Pull request (PR)\n\nFinally, visit [carbon-tutorial](https://github.com/carbon-design-system/carbon-tutorial) to \"Compare & pull request\". In doing so, make sure that you are comparing to `react-step-4` into `base: react-step-4`.\n\n_Note: Expect your tutorial step PRs to be reviewed by the Carbon team but not merged. We'll close your PR so we can keep the repository's remote branches pristine and ready for the next person!_\n","type":"Mdx","contentDigest":"abc307a776cfcf95fb17f7d06b4262b9","counter":1693,"owner":"gatsby-plugin-mdx"},"frontmatter":{"title":"4. Creating components","description":"Welcome to Carbon! This tutorial will guide you in creating a React app with the Carbon Design System.","tabs":["Overview","Step 1","Step 2","Step 3","Step 4","Step 5","Wrapping up"]},"exports":{},"rawBody":"---\ntitle: 4. Creating components\ndescription: Welcome to Carbon! This tutorial will guide you in creating a React app with the Carbon Design System.\ntabs:\n  ['Overview', 'Step 1', 'Step 2', 'Step 3', 'Step 4', 'Step 5', 'Wrapping up']\n---\n\nimport Preview from 'components/Preview';\n\n<PageDescription>\n\nWith two pages comprised entirely of Carbon components, let's revisit the\nlanding page and build a couple components of our own by using Carbon icons\nand tokens.\n\n</PageDescription>\n\n<AnchorLinks>\n\n<AnchorLink>Fork, clone and branch</AnchorLink>\n<AnchorLink>Review design</AnchorLink>\n<AnchorLink>Create components</AnchorLink>\n<AnchorLink>Use components</AnchorLink>\n<AnchorLink>Add styling</AnchorLink>\n<AnchorLink>Check accessibility</AnchorLink>\n<AnchorLink>Submit pull request</AnchorLink>\n\n</AnchorLinks>\n\n## Preview\n\nCarbon provides a solid foundation for building web applications through its color palette, layout, spacing, type, as well as common building blocks in the form of components. So far, we've only used Carbon components to build out two pages.\n\nNext, we're going to use Carbon assets to build application-specific components. We'll do so by including accessibility and responsive considerations all throughout.\n\nA [preview](https://react-step-5--carbon-tutorial.netlify.com) of what you'll build (see bottom of page):\n\n<Preview\n  height=\"400\"\n  title=\"Carbon Tutorial Step 4\"\n  src=\"https://react-step-5--carbon-tutorial.netlify.com\"\n  frameborder=\"no\"\n  allowtransparency=\"true\"\n  allowfullscreen=\"true\"\n  class=\"bx--iframe bx--iframe--border\"\n/>\n\n## Fork, clone and branch\n\nThis tutorial has an accompanying GitHub repository called [carbon-tutorial](https://github.com/carbon-design-system/carbon-tutorial) that we'll use as a starting point for each step. If you haven't forked and cloned that repository yet, and haven't added the upstream remote, go ahead and do so by following the [step 1 instructions](/tutorial/react/step-1#fork-clone--branch).\n\n### Branch\n\nWith your repository all set up, let's check out the branch for this tutorial step's starting point.\n\n```bash\n$ git fetch upstream\n$ git checkout -b react-step-4 upstream/react-step-4\n```\n\n_Note: This builds on top of step 3, but be sure to check out the upstream step 4 branch because it includes the static assets required to get through this step._\n\n### Build and start app\n\nInstall the app's dependencies (in case you're starting fresh in your current directory and not continuing from the previous step):\n\n```bash\n$ yarn\n```\n\nThen, start the app:\n\n```bash\n$ yarn start\n```\n\nYou should see something similar to where the [previous step](/tutorial/react/step-3) left off.\n\n## Review design\n\nHere's what we're building – an informational section that has a heading and three subheadings. Each subheading has accompanying copy and a pictogram. We'll assume that this informational section is used elsewhere on the site, meaning it's a great opportunity to build it as a resusable component. As for naming, we'll call it an `InfoSection` with three `InfoCard`s as children.\n\n![Info section layout](../shared/step-4/images/info-layout.png)\n\n<Caption>Info section layout</Caption>\n\n## Create components\n\nFirst we need files for the components, so create an `Info` folder in `src/components`. Even though we're building multiple components, their names all start with `Info`, so it makes sense to have them share one folder in components. Create these files:\n\n### Add files\n\n```bash\nsrc/components/Info\n├──_info.scss\n├──index.js\n└──Info.js\n```\n\nImport `_info.scss` in `app.scss` after all of the `carbon-component` imports.\n\n```scss path=src/app.scss\n@import './components/Info/info.scss';\n```\n\nLike our other components, `index.js` will serve as an entrypoint. Since `Info.js` will export mutliple components, we'll use the `*` wildcard in the entrypoint export.\n\n```javascript path=src/components/Info/index.js\nexport * from './Info';\n```\n\n### InfoSection component\n\nLet's create the parent component that includes the \"The Principles\" heading. That markup currently looks like this in `LandingPage.js`:\n\n```html path=src/content/LandingPage/LandingPage.js\n<div className=\"bx--row landing-page__r3\">\n  <div className=\"bx--col-md-4 bx--col-lg-4\">\n    <h3 className=\"landing-page__label\">The Principles</h3>\n  </div>\n  <div className=\"bx--col-md-4 bx--col-lg-4\">Carbon is Open</div>\n  <div className=\"bx--col-md-4 bx--col-lg-4\">Carbon is Modular</div>\n  <div className=\"bx--col-md-4 bx--col-lg-4\">Carbon is Consistent</div>\n</div>\n```\n\nWe want to do a few things when abstracting it to a component. First, we only want Carbon (`bx--`) and this component's class names; we don't want to include `landing-page__r3` as that's specific to the landing page. For that we'll use React `props` so we can pass in and use `props.className`.\n\nWe'll also:\n\n- Add component class names like `info-section` and `info-section__heading`\n- Semantically use `<section>` instead of `<div>`\n- Update the grid columns to match the design\n- Replace `The Principles` with `{props.heading}`\n- Replace columns 2 - 4 with `{props.children}`\n\nUsing `props` we can render any heading and any number of children components (`InfoCard` that we'll build soon.)\n\n```javascript path=src/components/Info/Info.js\nimport React from 'react';\n\nconst InfoSection = props => (\n  <section className={`bx--row ${props.className} info-section`}>\n    <div className=\"bx--col-md-8 bx--col-lg-4 bx--col-xlg-3\">\n      <h3 className=\"info-section__heading\">{props.heading}</h3>\n    </div>\n    {props.children}\n  </section>\n);\n```\n\nAt this point let's add styling for the new class names that we just added.\n\n```scss path=src/components/Info/_info.scss\n.info-section__heading {\n  @include carbon--type-style('heading-01');\n}\n```\n\n### InfoCard component\n\nNext up we're going to build a component for columns 2 - 4, which currently looks like `<div className=\"bx--col-md-4 bx--col-lg-4\">Carbon is Open</div>`. At the bottom of `Info.js`, add:\n\n```javascript path=src/components/Info/Info.js\nconst InfoCard = props => {\n  return (\n    <article className=\"info-card bx--col-md-4 bx--col-lg-4 bx--col-xlg-3 bx--offset-xlg-1\">\n      <h4 className=\"info-card__heading\">{props.heading}</h4>\n      <p className=\"info-card__body\">{props.body}</p>\n      {props.icon}\n    </article>\n  );\n};\n\nexport { InfoSection, InfoCard };\n```\n\n_Note: Make sure to export the two components!_\n\nIn doing so, we:\n\n- Used the semantic `<article>` instead of `<div>`\n- Added `info-card` classes\n- Used `props` to render the heading, body copy, and icon\n- Set columns to match the grid\n\n_Note: At extra large viewports, we are using _`bx--col-xlg-3 bx--offset-xlg-1`_ so each column takes up 3 of the 16 grid columns, with a 1 column offset._\n\n## Use components\n\nNothing is styled yet, but with our components built let's put them to use. In `LandingPage.js`, import the components towards the top of the file.\n\n```javascript path=src/content/LandingPage/LandingPage.js\nimport { InfoSection, InfoCard } from '../../components/Info';\n```\n\nWhile we're at the top of `LandingPage.js`, import the icons that we'll need as well.\n\n```javascript path=src/content/LandingPage/LandingPage.js\nimport Globe32 from '@carbon/icons-react/lib/globe/32';\nimport PersonFavorite32 from '@carbon/icons-react/lib/person--favorite/32';\nimport Application32 from '@carbon/icons-react/lib/application/32';\n```\n\n_Note: You'll notice that these 32px icons aren't the pictograms as designed. The Carbon team is currently working on adding pictograms to the icons packages. Until then, we'll use the biggest SVGs._\n\nWith everything imported, replace the current:\n\n```html path=src/content/LandingPage/LandingPage.js\n<div className=\"bx--row landing-page__r3\">\n  <div className=\"bx--col-md-4 bx--col-lg-4\">\n    <h3 className=\"landing-page__label\">The Principles</h3>\n  </div>\n  <div className=\"bx--col-md-4 bx--col-lg-4\">Carbon is Open</div>\n  <div className=\"bx--col-md-4 bx--col-lg-4\">Carbon is Modular</div>\n  <div className=\"bx--col-md-4 bx--col-lg-4\">Carbon is Consistent</div>\n</div>\n```\n\nWith the new components:\n\n<!-- prettier-ignore-start -->\n```javascript path=src/content/LandingPage/LandingPage.js\n<InfoSection heading=\"The Principles\" className=\"landing-page__r3\">\n  <InfoCard\n    heading=\"Carbon is Open\"\n    body=\"It's a distributed effort, guided by the principles of the open-source movement. Carbon's users are also it's makers, and everyone is encouraged to contribute.\"\n    icon={<PersonFavorite32/>}\n  />\n  <InfoCard\n    heading=\"Carbon is Modular\"\n    body=\"Carbon's modularity ensures maximum flexibility in execution. It's components are designed to work seamlessly with each other, in whichever combination suits the needs of the user.\"\n    icon={<Application32/>}\n  />\n  <InfoCard\n    heading=\"Carbon is Consistent\"\n    body=\"Based on the comprehensive IBM Design Language, every element and component of Carbon was designed from the ground up to work elegantly together to ensure consistent, cohesive user experiences.\"\n    icon={<Globe32/>}\n  />\n</InfoSection>\n```\n<!-- prettier-ignore-end -->\n\n_Note: Now is a good time to resize your browser from phone to extra large viewport widths to see how the responsive grid is working before we add further styling._\n\n## Add styling\n\nHere's our design showing the spacing tokens that we need to add. We also need to set type style and borders.\n\n![Info section spacing](../shared/step-4/images/info-spacing.png)\n\n### Layout\n\nStarting with layout, add the following to `src/components/Info/_info.scss`.\n\n```scss path=src/components/Info/_info.scss\n.info-card {\n  margin-top: $spacing-09;\n  display: flex;\n  flex-direction: column;\n\n  svg {\n    margin-top: $spacing-09;\n  }\n\n  // top border in only small breakpoints to prevent overrides\n  @include carbon--breakpoint-down(md) {\n    &:not(:nth-child(2)) {\n      border-top: 1px solid $ui-03;\n      padding-top: $spacing-09;\n    }\n  }\n\n  // left border in just the 2nd column items\n  @include carbon--breakpoint(md) {\n    &:nth-child(odd) {\n      border-left: 1px solid $ui-03;\n    }\n  }\n\n  // left border in all items\n  @include carbon--breakpoint(lg) {\n    margin-top: 0;\n    border-left: 1px solid $ui-03;\n\n    svg {\n      margin-top: $layout-06;\n    }\n  }\n}\n```\n\nOnce you save, go ahead and resize your browser to see the responsive layout at the different breakpoints. Make sure to review these color and spacing tokens. There are also a few breakpoint mixins that may be new to you. The `@carbon/layout` [SassDoc](https://github.com/carbon-design-system/carbon/blob/master/packages/layout/docs/sass.md) is a great reference to see what all is available.\n\n### Type\n\nOur `InfoCard` headings look to be too small. We need to increase their font sizes according to the design spec with:\n\n```scss path=src/components/Info/_info.scss\n.info-card__heading {\n  @include carbon--type-style('productive-heading-03');\n}\n```\n\nAlso, the design has the last word in each subheading as bold. To accomplish that, add this helper function after the import in `Info.js`.\n\n```javascript path=src/components/Info/Info.js\n// Take in a phrase and separate the third word in an array\nfunction createArrayFromPhrase(phrase) {\n  const splitPhrase = phrase.split(' ');\n  const thirdWord = splitPhrase.pop();\n  return [splitPhrase.join(' '), thirdWord];\n}\n```\n\nThen, update `InfoCard` to use `createArrayFromPhrase`.\n\n```javascript path=src/components/Info/Info.js\nconst InfoCard = props => {\n  const splitHeading = createArrayFromPhrase(props.heading);\n\n  return (\n    <article className=\"info-card bx--col-md-4 bx--col-lg-4 bx--col-xlg-3 bx--offset-xlg-1\">\n      <h4 className=\"info-card__heading\">\n        {`${splitHeading[0]} `}\n        <strong>{splitHeading[1]}</strong>\n      </h4>\n      <p className=\"info-card__body\">{props.body}</p>\n      {props.icon}\n    </article>\n  );\n};\n```\n\nFinally, add the declaration block in `_info.scss` to set `InfoCard` body copy styles and to bottom-align the icons.\n\n```scss path=src/components/Info/_info.scss\n.info-card__body {\n  margin-top: $spacing-06;\n  flex-grow: 1; // fill space so icons are bottom aligned\n  @include type-style('body-long-01');\n\n  // prevent large line lengths between small and medium viewports\n  @include carbon--breakpoint-between(321px, md) {\n    max-width: 75%;\n  }\n}\n```\n\n## Check accessibility\n\nWe've added new markup and styles, so it's a good practice to check [DAP](https://www.ibm.com/able/dynamic-assessment-plug-in.html) and make sure our rendered markup is on the right track for accessibility.\n\nWith the browser extension installed, Chrome in this example, open Dev Tools and run DAP.\n\n![DAP violations](../shared/step-4/images/DAP-violations.png)\n\n<Caption>DAP violations</Caption>\n\nThat first violation is for the off-screen \"skip to content\" link. This link isn't shown and is used to assist screen reading, so the color contrast violation can be ignored.\n\nBut, those three other violations came from the `<article>` element used in new `InfoCard`. Since the `<article>` element requires a label, it seems like we may be using the wrong semantic element. A humble `<div>` will suffice.\n\nIn `Info.js`, replace the `<article>` opening and closing tags with `<div>` tags.\n\n## Submit pull request\n\nWe're going to submit a pull request to verify completion of this tutorial step.\n\n### Continuous integration (CI) check\n\nRun the CI check to make sure we're all set to submit a pull request.\n\n```bash\n$ yarn ci-check\n```\n\n_Note: Having issues running the CI check? [Step 1](</tutorial/react/step-1#continuous-integration-(ci)-check>) has troubleshooting notes that may help._\n\n### Git commit and push\n\nBefore we can create a pull request, stage and commit all of your changes:\n\n```bash\n$ git add --all && git commit -m \"feat(tutorial): complete step 4\"\n```\n\nThen, push to your repository:\n\n```bash\n$ git push origin react-step-4\n```\n\n_Note: Having issues pushing your changes? [Step 1](/tutorial/react/step-1#git-commit-and-push) has troubleshooting notes that may help._\n\n### Pull request (PR)\n\nFinally, visit [carbon-tutorial](https://github.com/carbon-design-system/carbon-tutorial) to \"Compare & pull request\". In doing so, make sure that you are comparing to `react-step-4` into `base: react-step-4`.\n\n_Note: Expect your tutorial step PRs to be reviewed by the Carbon team but not merged. We'll close your PR so we can keep the repository's remote branches pristine and ready for the next person!_\n","fileAbsolutePath":"/zeit/1dde86ed/src/pages/tutorial/react/step-4.mdx"}}}}