Button component with `loading` state.

Quite often there is a need for a button that would show loading state while an operation is performed (request to the server, etc.). Most useful for the success buttons in the modals: one should not dismiss the modal unless the operation was successfully committed on the server. Hence, the button should indicate some level of "progress" or "loading" while the operation is in flight.

At the moment, there are several places in the product where a workaround is implemented, based on the following pattern, relying on the <gl-loading-icon>:

export default {
  ...
  data() {
    isInProgress: false
  },
  methods: {
   someMethod() {
     this.isInProgress = true;
     // Some Long Operation
     this.isInProgress = false;   
   }
  }
}
<template>
  <gl-button @click="someMethod">
    <gl-loading-icon v-if="isInProgress"/>
    My Action
  </gl-button>
</template>

This is how it looks like in the interface:

Default isInProgress
Screenshot_2019-10-29_at_11.59.01 Screenshot_2019-10-29_at_11.58.27

There are a couple of issues with this pattern: first of all, the loading icon is not aligned properly with the text and in order to achieve this, every instance of such a button needs styling adjustments (as both the text and the icon do not belong to the button itself and are rendered within generic <slot>). Also, showing the loading icon in-front the text shifts the button text and degrades usability.

Proposal

Either create a new button component with loading data, or extend the existing GlButton to support it.

Hide text (visibility: hidden instead of display: none to preserve button's dimensions) while isInProgress, showing only the centered spinner (absolute positioning). The button might get disabled CSS class and then we should get something like this:

Screenshot_2019-10-29_at_12.05.08

However, we might want to preserve the button's color even if the button is disabled while isInProgress and then it would look similar to:

Screenshot_2019-10-29_at_12.05.18

To do:

  • Add this as a new component variant that will be integrated upon need during feature implementation. frontend
  • Add component examples in gitlab-ui demonstrating the loading state. frontend
  • Document this button functionality in the button usage guidelines. UX
  • [ ]Add component examples in design.gitlab.com demonstrating the loading state. UX
  • Update button design specs to include this new loading button variant. UX
  • Open an issue to track and replace the existing loading_button components. frontend
  • Open an issue to track and replace existing buttons using a spinner, like the issue edit actions component.
Edited by Laura Montemayor