Skip to content

Commit

Permalink
Merge pull request #159 from Dataport/feature/custom-loading-indicator
Browse files Browse the repository at this point in the history
Add loader styles
  • Loading branch information
dopenguin authored Sep 13, 2024
2 parents 9282d8e + 79b91a2 commit 21763ff
Show file tree
Hide file tree
Showing 23 changed files with 650 additions and 31 deletions.
2 changes: 2 additions & 0 deletions packages/plugins/LoadingIndicator/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
## unpublished

- Refactor: Remove redundant prop-forwarding by only using one component.
- Feature: Add new optional parameter `loaderStyle` to choose between different loader styles.
- Feature: Add new mutation `setLoaderStyle` to choose between different loader styles at runtime.

## 1.1.0

Expand Down
31 changes: 29 additions & 2 deletions packages/plugins/LoadingIndicator/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ A generic loading indicator that may be used by any plugin or outside procedure

## Configuration

### loadingIndicator

| fieldName | type | description |
| - | - | - |
| loaderStyle | enum['CircleLoader', 'BasicLoader', 'none', 'RingLoader', 'RollerLoader', 'SpinnerLoader', 'v-progress-linear']? | Choose between different loader styles. Defaults to 'v-progress-linear' (Vuetify loader). |

For details on the `displayComponent` attribute, refer to the [Global Plugin Parameters](../../core/README.md#global-plugin-parameters) section of `@polar/core`.

Example configuration:
Expand All @@ -26,18 +32,39 @@ map.$store.commit('plugin/loadingIndicator/addLoadingKey', key)
map.$store.commit('plugin/loadingIndicator/removeLoadingKey', key)
```

![Loading indicator example](./readme_loadingIndicator_example.png)

The key must be unique and is kept track of via a Set. It can't be added multiple times, and removing it once always removes it altogether. It is advised to use a key like `{my-plugin-or-application-name}-{procedure-name}` to avoid name conflicts. The LoadingIndicator will usually be used for asynchronous code.

As such, **always call `removeLoadingKey` in the `finally` section of your code** to prevent hanging loading indicators.

```js
// change loader style at runtime
map.$store.commit('plugin/loadingIndicator/setLoaderStyle', loaderStyle)
```

#### Supported `loaderStyle` options

<table align="center">
<tr align="center">
<td width="33%" align="center"><img src="./assets/VuetifyLoader.gif" alt="v-progress-linear" height="120px" style="object-fit: none;"><div>v-progress-linear</div></td>
<td width="33%" align="center"><img src="./assets/BasicLoader.gif" alt="BasicLoader" height="120px" style="object-fit: contain;"><div>BasicLoader</div></td>
<td width="33%" align="center"><img src="./assets/RingLoader.gif" alt="RingLoader" height="120px" style="object-fit: contain;"><div>RingLoader</div></td>
</tr>
<tr align="center">
<td width="33%" align="center"><img src="./assets/RollerLoader.gif" alt="RollerLoader" height="120px" style="object-fit: contain;"><div>RollerLoader</div></td>
<td width="33%" align="center"><img src="./assets/CircleLoader.gif" alt="CircleLoader" height="120px" style="object-fit: contain;"><div>CircleLoader</div></td>
<td width="33%" align="center"><img src="./assets/SpinnerLoader.gif" alt="SpinnerLoader" height="120px" style="object-fit: contain;"><div>SpinnerLoader</div></td>
</tr>
</table>

It is also possible to choose `none` as a `loaderStyle` to hide the loader.

### Getters

You may desire to listen to whether the loader is currently being shown.

| fieldName | type | description |
| - | - | - |
| loaderStyle | string | The current loader style. |
| showLoader | boolean | Whether the layer is currently shown. |

```js
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,19 @@
<div v-if="showLoader">
<v-card>
<v-card-text>
{{ $t('common:plugins.loadingIndicator.loading') }}
<v-progress-linear indeterminate color="primary" class="mb-0" />
<v-container>
<v-row justify="center">
{{ $t('common:plugins.loadingIndicator.loading') }}
</v-row>
<v-row v-if="loaderStyle !== 'none'">
<component
:is="loaderStyle"
indeterminate
color="primary"
class="mb-0"
/>
</v-row>
</v-container>
</v-card-text>
</v-card>
</div>
Expand All @@ -12,11 +23,23 @@
<script lang="ts">
import Vue from 'vue'
import { mapGetters } from 'vuex'
import RollerLoader from './loaderStyles/Roller.vue'
import CircleLoader from './loaderStyles/Circle.vue'
import SpinnerLoader from './loaderStyles/Spinner.vue'
import RingLoader from './loaderStyles/Ring.vue'
import BasicLoader from './loaderStyles/Basic.vue'
export default Vue.extend({
name: 'LoadingIndicator',
components: {
RollerLoader,
CircleLoader,
SpinnerLoader,
RingLoader,
BasicLoader,
},
computed: {
...mapGetters('plugin/loadingIndicator', ['showLoader']),
...mapGetters('plugin/loadingIndicator', ['showLoader', 'loaderStyle']),
},
})
</script>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
<template>
<div class="lds-default">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</template>

<script lang="ts">
import Vue from 'vue'
/**
* This loader is the lds-default loader from https://loading.io/css/.
* It was renamed to BasicLoader to avoid confusion with the default loader.
*/
export default Vue.extend({
name: 'BasicLoader',
})
</script>

<style lang="scss" scoped>
.lds-default {
/* change color here */
color: var(--polar-primary);
}
.lds-default,
.lds-default div {
box-sizing: border-box;
}
.lds-default {
display: inline-block;
position: relative;
width: 80px;
height: 80px;
}
.lds-default div {
position: absolute;
width: 6.4px;
height: 6.4px;
background: currentColor;
border-radius: 50%;
animation: lds-default 1.2s linear infinite;
}
.lds-default div:nth-child(1) {
animation-delay: 0s;
top: 36.8px;
left: 66.24px;
}
.lds-default div:nth-child(2) {
animation-delay: -0.1s;
top: 22.08px;
left: 62.29579px;
}
.lds-default div:nth-child(3) {
animation-delay: -0.2s;
top: 11.30421px;
left: 51.52px;
}
.lds-default div:nth-child(4) {
animation-delay: -0.3s;
top: 7.36px;
left: 36.8px;
}
.lds-default div:nth-child(5) {
animation-delay: -0.4s;
top: 11.30421px;
left: 22.08px;
}
.lds-default div:nth-child(6) {
animation-delay: -0.5s;
top: 22.08px;
left: 11.30421px;
}
.lds-default div:nth-child(7) {
animation-delay: -0.6s;
top: 36.8px;
left: 7.36px;
}
.lds-default div:nth-child(8) {
animation-delay: -0.7s;
top: 51.52px;
left: 11.30421px;
}
.lds-default div:nth-child(9) {
animation-delay: -0.8s;
top: 62.29579px;
left: 22.08px;
}
.lds-default div:nth-child(10) {
animation-delay: -0.9s;
top: 66.24px;
left: 36.8px;
}
.lds-default div:nth-child(11) {
animation-delay: -1s;
top: 62.29579px;
left: 51.52px;
}
.lds-default div:nth-child(12) {
animation-delay: -1.1s;
top: 51.52px;
left: 62.29579px;
}
@keyframes lds-default {
0%,
20%,
80%,
100% {
transform: scale(1);
}
50% {
transform: scale(1.5);
}
}
</style>
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<template>
<div class="lds-circle"><div></div></div>
</template>

<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
name: 'CircleLoader',
})
</script>

<style lang="scss" scoped>
.lds-circle {
color: var(--polar-primary);
}
.lds-circle,
.lds-circle div {
box-sizing: border-box;
}
.lds-circle {
display: inline-block;
transform: translateZ(1px);
}
.lds-circle > div {
display: inline-block;
width: 64px;
height: 64px;
margin: 8px;
background: currentColor;
border-radius: 50%;
animation: lds-circle 2.4s cubic-bezier(0, 0.2, 0.8, 1) infinite;
}
@keyframes lds-circle {
0%,
100% {
animation-timing-function: cubic-bezier(0.5, 0, 1, 0.5);
}
0% {
transform: rotateY(0deg);
}
50% {
transform: rotateY(1800deg);
animation-timing-function: cubic-bezier(0, 0.5, 0.5, 1);
}
100% {
transform: rotateY(3600deg);
}
}
</style>
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<template>
<div class="lds-ring">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</template>

<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
name: 'RingLoader',
})
</script>

<style lang="scss" scoped>
.lds-ring {
/* change color here */
color: var(--polar-primary);
}
.lds-ring,
.lds-ring div {
box-sizing: border-box;
}
.lds-ring {
display: inline-block;
position: relative;
width: 80px;
height: 80px;
}
.lds-ring div {
box-sizing: border-box;
display: block;
position: absolute;
width: 64px;
height: 64px;
margin: 8px;
border: 8px solid currentColor;
border-radius: 50%;
animation: lds-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
border-color: currentColor transparent transparent transparent;
}
.lds-ring div:nth-child(1) {
animation-delay: -0.45s;
}
.lds-ring div:nth-child(2) {
animation-delay: -0.3s;
}
.lds-ring div:nth-child(3) {
animation-delay: -0.15s;
}
@keyframes lds-ring {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>
Loading

0 comments on commit 21763ff

Please sign in to comment.