contentful / forma-36

A design system by Contentful
https://f36.contentful.com
MIT License
331 stars 81 forks source link

💡 Proposal - Progress/Loading state button #1621

Open imshuffling opened 2 years ago

imshuffling commented 2 years ago

Forma 36 contribution proposal

Currently working on a custom app, where it has a button to create a new piece of content onClick.

When the onClick happens its field input data from microservices and other locations.

During this time I wanted to have a loading/progress state So I thought i would modify an

https://user-images.githubusercontent.com/739061/145859920-02fa39ff-8d02-4fa9-9143-abb8a26ddf18.mov

Some example code... I'm setting the progress bar with in state being bumped along inside an async function call (There's probably a better way to do this) :)

<div className="btn-container">
  <button className="btn-wrapper" onClick={createBrochure}>
    <div className="btn">
      Creating <Spinner color="white" />
    </div>
    <div className="progress" style={{ width: loadingBtn }}></div>
  </button>
</div>
.btn-container {
  position: relative;
  width: 148px;
}

.btn-wrapper {
  background-color: #036fe3;
  background-size: 100% 200%;
  border: .0625rem solid #036fe3;
  border-radius: 6px;
  box-shadow: 0 1px 0 rgba(25,37,50,.1);
  box-sizing: border-box;
  display: inline-block;
  font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;
  font-size: .875rem;
  font-weight: 500;
  height: 2.5rem;
  overflow: hidden;
  padding: 0;
  text-decoration: none;
  transition: background .1s ease-in-out,opacity .2s ease-in-out,border-color .2s ease-in-out;
  vertical-align: middle;
  color: white;
  width: 100%;
  cursor: pointer;
}

.btn-wrapper .btn {
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  line-height: 39px;
  text-align: center;
  z-index: 10;
  opacity: 1;
}

.btn-wrapper .progress {
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  width: 50%;
  z-index: 5;
  background: #0059C8;
  border-radius: 6px;
  transition: width 2s ease-in-out;
}
imshuffling commented 2 years ago

Soo I'm proposing can we do something like this?

progress={width} can be a prop with a percentage value

So for example. <Button buttonType="primary" isLoading={true} progress={width}>Create Brochure</Button>

burakukula commented 2 years ago

Hey @imshuffling! Thanks a lot for bringing this topic! Great stuff! 👏 @fabe @domarku @damann how would you see this topic from a design perspective? Maybe you thought of some sort of progress bar already?

damann commented 2 years ago

I think it's great to have more distinguished ways of indicating ongoing processes.

I'd like to suggest a few usage guidelines:

If we (roughly) know the duration: < 10 sec, use the bouncy dots loop

10 sec, use the percentage bar For processes that take longer than 10 sec. show an estimate of when the process will be finished, ideally as time otherwise in percentage (design tbd @domarku I'd like to get your perspective here). If we don't know the duration, provide additional context alongside the progress indicator.

Another piece of advice – that we don't have a pattern for yet – is to allow processes to run in the background.

Don't mix dots and percentage bars (as in the video)

imshuffling commented 2 years ago

Thanks @damann, some good thoughts. In my usecase because I'm relying on external microservices I wanted to show something a bit more than bouncy dots.. It can be around the 10sec mark :)

Another design idea i was thinking about is having an underline progress bar which maybe more subtle.

damann commented 2 years ago

@imshuffling I really liked your idea of the button filling up. I wanted to provide some guidance around how to choose one of the two options.

github-actions[bot] commented 2 years ago

Marking issue as stale since there was no acitivty for 30 days