Translator: miaoYu

The original link

The introduction

This article series will walk you through how to build your own component library by creating one.

This is part 3. If you haven’t read Parts 1 and 2, I suggest you do.

We will discuss:

  • Create a Label element

  • Make our button elements more extensible

  • Consistency of element size

Add a Label element

$ touch lib/elements/Label.js

Copy the code
import PropTypes from 'prop-types';
import styled from 'styled-components';

Copy the code
import * as colors from '.. /styles/colors';Copy the code

const Label = styled.label`
  color: ${({ color }) => colors[color]};
  display: inline-block;
  font-size: 14px;
  font-weight: ${({ fontWeight }) => fontWeight};
  margin: 8px 0;
  text-transform: ${({ textTransform }) => textTransform};
  transition: all 300ms ease;
`;

Copy the code
Label.propTypes = {
  color: PropTypes.string,
  fontWeight: PropTypes.number,
  textTransform: PropTypes.string,
};

Copy the code
Label.defaultProps = {
  color: 'silver',
  fontWeight: 400,
  textTransform: 'uppercase',
};

Copy the code
export default Label;

Copy the code

It looks like a lot of code, but most of it looks like a Button element. The user can pass in the color, font-weight, and text-transform parameters as props. If not, set the default value. Now we create the path in lib/index.js.

import Button from './elements/Button';
import Label from './elements/Label';

Copy the code
module.exports = {
  Button,
  Label,
};

Copy the code

Cool. Now we can play with component-lib-playground.

Note: Make sure NPM run build:watch and NPM run Lint :watch run in your component library, and _npm run dev_ run in your application.

. import { Button, Label } from 'component-lib' ...Copy the code
const App = ({ name }) => { return ( <div> <Label>Hello, {name}! </Label> <Button bgColor=""orange""> Click Me! </Button> </div> ); }; .Copy the code

If all goes well, you should see in your browser:

It looks like the default values we set are working, you can also try passing different parameters. ?

At this point, you might be wondering why font size, line-height, and padding are set to static parameters, but you’re obviously right, these parameters should be set to dynamic additions. But we should give the user a good size specification instead of letting them enter arbitrary font size values into the component. We will divide reasonable sizes, take Labels as an example, we will set small, medium, and large, and the user passes these three sizes through props. To implement this, we add the following code to the Label:

. const labelSizes = { small: { 'font-size': '12px', 'line-height': '12px', }, medium: { 'font-size': '14px', 'line-height': '16px', }, large: { 'font-size': '16px', 'line-height': '16px', }, };Copy the code
const Label = styled.label` color: ${({ color }) => colors[color]}; display: inline-block; font-size: ${({ size }) => labelSizes[size]['font-size']}; line-height: ${({ size }) => labelSizes[size]['line-height']}; .Copy the code
Label.defaultProps = { color: 'silver', fontWeight: 400, size: 'medium', textTransform: 'uppercase', }; .Copy the code

Wait, how do YOU get the value of FONT sizes? Any choice?

Good question. It’s not arbitrary, of course. Discerning people will notice that most of the time we use the eight-point grid system. Because it’s hard to keep spacing consistent when creating our component library. A good solution is to choose a “grid system”. We now use an “eight-point grid system”, which means that all spacing and dimensions are multiples of 8px. You choose 8,10 or 12 as a multiple, it doesn’t matter. The most important goal is to avoid generating components that don’t understand the dimensions. According to the eight-point grid system, that means we keep the sizes of “font-sizes” and “line-height” in multiples of eight. So our font size for “medium” should be 16px.

Note: if you want to learn more about the “Eight Point grid system” there is a great article if you want to learn more about creating consistent grid systems read this great article.

I see. But the label size of medium is 14px, not 16px?

Another good question. The label label shows some metrics and labels that should not allocate our attention. In fact, the best label is the one we read and forget. To sum up, if our overall medium font is set to 16px, then our label label should be slightly smaller, such as 2px, to achieve visual degradation. I can also use silver to achieve the same effect. Note that we also need to change the “line-height” to achieve consistency.

Ok, now that the Label is set, let’s also add some dynamic dimensions to the Button.

Add dimensions to the Button

There are many types of buttons, so its size is a bit confusing. We wanted to meet the needs of our users, but we also needed to create consistent sizes. So add the following code to Button:

. const buttonSizes = { small: { 'font-size': '14px', 'line-height': '30px', padding: '0 8px', }, medium: { 'font-size': '16px', 'line-height': '40px', padding: '0 12px', }, large: { 'font-size': '18px', 'line-height': '50px', padding: '0 16px', }, wide: { 'font-size': '16px', 'line-height': '40px', padding: '0 36px', }, extraWide: { 'font-size': '16px', 'line-height': '40px', padding: '0 72px', }, fullWidth: { 'font-size': '16px', 'line-height': '40px', padding: '0 8px', }, };Copy the code
function setDisplay({ size }) {
  return size === 'fullWidth' ? 'block' : 'inline-block';
}

Copy the code
function setWidth({ size }) {
  return size === 'fullWidth' ? '100%' : 'initial';
}

Copy the code
const Button = styled.button` ... display: ${setDisplay}; font-size: ${({ size }) => buttonSizes[size]['font-size']}; line-height: ${({ size }) => buttonSizes[size]['line-height']}; . padding: ${({ size }) => buttonSizes[size]['padding']}; . width: ${setWidth}; . `;Copy the code
Button.defaultProps = {
  bgColor: 'blue',
  fontColor: 'white',
  size: 'medium',
};

Copy the code
.Copy the code

We added several dimensions: Small, medium, Large, wide, extraWide, and fullWidth, and we also added two methods, setDisplay and setWidth, to handle attributes. Separate these methods to make your code more readable.

Calculation of the padding

Let me talk a little bit about the relationship between font size, line-height, and padding. Remember I said earlier that we mostly follow an eight-point grid system. Yes, I’m going to break it this time. The Padding should be consistent on each edge, following this pattern:

line-height = font-size + 2(padding)

Copy the code

After calculation, it is as follows:

// small
line-height = 14 + 8(2) // (30px)

Copy the code
// medium
line-height = 16 + 12(2) // (40px)

Copy the code
// large
line-height = 16 + 18(2) // (50px)

Copy the code

Test button size

Okay, now that you understand some of the method behind the sizing, let’s test this out in the playground app. We’ll add the different button sizes so you can see the variations. We’re wrapping the buttons in divs to put each one on a new line.

Ok, let’s test it in the component-lib-playground application. Add different kinds of size buttons so you can see the changes.

. const App = ({ name }) => { return ( <div> <Label size=""small"">Hello, {name}! </Label> <div> <Button bgColor=""green"" size=""small"" > small </Button> </div> <div> <Button bgColor=""yellow"" size=""medium"" > medium </Button> </div> <div> <Button bgColor=""orange"" size=""large"" > large </Button> </div> <div>  <Button size=""wide"" > wide </Button> </div> <div> <Button bgColor=""pink"" size=""extraWide"" > extra wide </Button> </div> <div> <Button bgColor=""purple"" size=""fullWidth"" > full width </Button> </div> </div> ); }; .Copy the code

If all goes well, here’s what you should see:

Buttons in different sizes and colors.

The last

Great! Our buttons have a consistent size and are easier to use. And we have a simple API for our users. They can quickly create a button, regardless of how it is implemented. We also added a tag element that will be useful when we finally build the component. In Part 4, we’ll add my third and final element: the multi-line text input field!

Note: Save to submit your code.

$ git status
$ git add -A
$ git commit -m 'Adds Label element and Button sizes'

Copy the code

Part four is being written, please look forward to it! 🙂