How to make Button Variants with React, TypeScript and Styled Components


You can find both demo and source code at

Most apps have three types of buttons: primary, ghost, and outlined. Let's make those buttons with React, TypeScript, and styled-components so we can take them to a new project, change a few styles, and we are good to go!

To have less code, we'll build these buttons on top of the RectButton component. It can receive all of the button attributes and children. We allow rendering it as a div element. It's handy when we want to show a button inside an anchor element. Then there is a size property ranging from xs to xl; and three flags: disabled, loading, and rounded.

The component itself is simple. We render either spinner or children inside of the styled container. The container wraps the UnstyledButton to not drug unnecessary styles. First, we set the color to the text color, then we assign border-radius, simple transition, and center the content. Based on the size property, the button will have different horizontal padding, height, and font size. Then we set cursor and opacity based on flags.

With all basic styles defined on the RectButton, we can easily extend it to different types of buttons. The Primary button has only one extra property - kind. Based on this property, we'll choose background and hover. To not brake the component, we don't assign as to the container but rather propagate it to the RectButton component with the forwardAs property.

The ghost button also has a kind property that defines text color. The outlined button doesn't have variants and only changes the border and background properties of the base button.