DEV Community

Simon Nyström
Simon Nyström

Posted on • Originally published at newcurrent.se

Building a Progress Bar

Introduction

This is part of the UI Kit with React, TypeScript, Storybook and Tailwind, make sure you've checked out the previous entries in the series if you find anything confusing 😊.

In this series I aim to implement a basic progress bar and integrate it with Storybook.

This will be a simple component compared to the ones we've made previously.

The finished product will look like this:

progress-bar


The ProgressBar

In the project, create two files:

  • src/components/ProgressBar/ProgressBar.tsx
  • src/stories/ProgressBar/ProgressBar.stories.tsx

This component is so simple that we can write it all in one go without really making any intermediate steps, so let's do that:

// ProgressBar.tsx

export type ProgressBarProps = {
  progress: number;
  progressText?: string;
};

const ProgressBar = ({ progress, progressText = "" }: ProgressBarProps) => {
  // Make sure our value stays between 0 and 100.
  const _progress = Math.min(Math.max(0, progress), 100);
  return (
    <div className="flex flex-col items-center justify-center">
      <div className="w-full border-2 border-indigo-700 h-6 rounded-md">
        <div
          className="bg-indigo-500 h-full transition-all duration-250"
          style={{ width: `${_progress}%` }}
        ></div>
      </div>
      <span>{progressText}</span>
    </div>
  );
};

export default ProgressBar;
Enter fullscreen mode Exit fullscreen mode

There is nothing fancy going on in this component, basically we have an outer-most div to let us place the optional progressText where we want it to. There is also a wrapper for the progress bar outline and then there is the progress bar div itself which scales its width based on the progress (from 0 to 100).


Adding the Stories

In the file we created earlier, src/stories/ProgressBar/ProgressBar.stories.tsx, place the following:

import { ComponentMeta, Story } from "@storybook/react";
import ProgressBar, {
  ProgressBarProps,
} from "../../components/ProgressBar/ProgressBar";

export default {
  title: "Progress Bar",
  component: ProgressBar,
} as ComponentMeta<typeof ProgressBar>;

const Template: Story<ProgressBarProps> = (args) => (
  <div className="w-56">
    <ProgressBar {...args} />
  </div>
);

export const WithLoadingText = Template.bind({});
WithLoadingText.args = {
  progressText: "Loading...",
  progress: 23,
};

export const WithoutLoadingText = Template.bind({});
WithoutLoadingText.args = {
  progress: 50,
};
Enter fullscreen mode Exit fullscreen mode

This is a lot simpler than our stories from previous entries in this series, and it's nice to do something simpler for a change. This is all we need and we will now have two predefined stories, one with text and one without.


Running Storybook

To see how this actually looks in reality, we'll need to start our Storybook by running yarn storybook.

Run Storybook, visit http://localhost:6006 and you'll find the ProgressBar component in the sidebar.


Troubleshooting

If you can't get it to run, or have some other concerns, check it out from my repo and see if that works:

https://github.com/simon-nystrom/newcurrent-react-ui/tree/progressbar


Stay tuned for the next entry in the series 😊. What component would you like to see next?

Top comments (1)

Collapse
 
themikeyross profile image
TheMikeyRoss

how about the bundling and publishing part?