Skip to content

Commit

Permalink
Merge pull request #5100 from nextcloud-libraries/feat/noid/circular-…
Browse files Browse the repository at this point in the history
…progress

feat(NcProgressBar): add circular progress bar
  • Loading branch information
raimund-schluessler authored Jan 22, 2024
2 parents 95ee9b6 + 6425e8c commit d6b87ef
Showing 1 changed file with 132 additions and 33 deletions.
165 changes: 132 additions & 33 deletions src/components/NcProgressBar/NcProgressBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
-
- @author Marco Ambrosini <[email protected]>
-
- @copyright Copyright (c) 2024 Raimund Schlüßler <[email protected]>
- @author Raimund Schlüßler
-
- @license GNU AGPL version 3 or any later version
-
- This program is free software: you can redistribute it and/or modify
Expand All @@ -23,27 +26,73 @@
This is a simple progress bar component.
## Usage:

### Small
### Linear
```vue
<NcProgressBar :value="60" />
```

### Medium
```vue
<NcProgressBar :value="60" size="medium" />
<template>
<span>
Small
<NcProgressBar :value="20" />
<br>
Medium
<NcProgressBar :value="60" size="medium" />
<br>
Medium with color
<NcProgressBar :value="55" size="medium" color="green" />
<br>
Error
<NcProgressBar :value="80" :error="true" />
</span>
</template>
```

### error
### Circular
```vue
<NcProgressBar :value="60" :error="true" />
<template>
<span>
Default
<NcProgressBar type="circular" :value="55" />
<br />
Color
<NcProgressBar type="circular" :value="70" color="green" />
<br />
Error
<NcProgressBar type="circular" :value="60" :error="true" />
</span>
</template>
```

</docs>

<template>
<progress class="progress-bar vue"
<span v-if="type === 'circular'"
role="progressbar"
:aria-valuenow="value"
:style="{ '--progress-bar-height': height + 'px' }"
:class="{ 'progress-bar--error': error }"
:style="{'--progress-bar-height': height }"
class="progress-bar progress-bar--circular">
<svg :height="height"
:width="height">
<circle stroke="currentColor"
fill="transparent"
:stroke-dasharray="`${progress * circumference} ${(1 - progress) * circumference}`"
:stroke-dashoffset="0.25*circumference"
:stroke-width="stroke"
:r="radiusNormalized"
:cx="radius"
:cy="radius" />
<circle stroke="var(--color-background-darker)"
fill="transparent"
:stroke-dasharray="`${(1 - progress) * circumference} ${progress * circumference}`"
:stroke-dashoffset="(0.25 - progress) * circumference"
:stroke-width="stroke"
:r="radiusNormalized"
:cx="radius"
:cy="radius" />
</svg>
</span>
<progress v-else
class="progress-bar progress-bar--linear vue"
:class="{ 'progress-bar--error': error }"
:style="{'--progress-bar-height': height + 'px' }"
:value="value"
max="100" />
</template>
Expand All @@ -70,12 +119,14 @@ export default {
* Possible values:
* - 'small' (default)
* - 'medium'
* - Number
* @type {'small'|'medium'|number}
*/
size: {
type: String,
type: [String, Number],
default: 'small',
validator(value) {
return ['small', 'medium'].indexOf(value) !== -1
return ['small', 'medium'].includes(value) || typeof value === 'number'
},
},
/**
Expand All @@ -85,45 +136,93 @@ export default {
type: Boolean,
default: false,
},
/**
* ProgressBar type
*/
type: {
type: String,
default: 'linear',
validator(value) {
return ['linear', 'circular'].includes(value)
},
},
color: {
type: String,
default: null,
},
},
data() {
return {
stroke: 4,
}
},
computed: {
height() {
if (this.type === 'circular') {
if (Number.isInteger(this.size)) {
return this.size
}
return 44
}
if (this.size === 'small') {
return '4px'
return 4
} else if (this.size === 'medium') {
return 6
}
return '6px'
return this.size
},
progress() {
return this.value / 100
},
radius() {
return this.height / 2
},
radiusNormalized() {
return this.radius - 3 * this.stroke
},
circumference() {
return this.radiusNormalized * 2 * Math.PI
},
},
}
</script>

<style lang="scss" scoped>
.progress-bar {
display: block;
height: var(--progress-bar-height);
width: 100%;
overflow: hidden;
border: 0;
padding: 0;
background: var(--color-background-dark);
border-radius: calc(var(--progress-bar-height) / 2);
// Browser specific rules
&::-webkit-progress-bar {
height: var(--progress-bar-height);
background-color: transparent;
}
&::-webkit-progress-value {
background: var(--gradient-primary-background);
--progress-bar-color: v-bind(color);
&--linear {
width: 100%;
overflow: hidden;
border: 0;
padding: 0;
background: var(--color-background-dark);
border-radius: calc(var(--progress-bar-height) / 2);
// Browser specific rules
&::-webkit-progress-bar {
height: var(--progress-bar-height);
background-color: transparent;
}
&::-webkit-progress-value {
background: var(--progress-bar-color, var(--gradient-primary-background));
border-radius: calc(var(--progress-bar-height) / 2);
}
&::-moz-progress-bar {
background: var(--progress-bar-color, var(--gradient-primary-background));
border-radius: calc(var(--progress-bar-height) / 2);
}
}
&::-moz-progress-bar {
background: var(--gradient-primary-background);
border-radius: calc(var(--progress-bar-height) / 2);
&--circular {
width: var(--progress-bar-height);
color: var(--progress-bar-color, var(--color-primary-element));
}
&--error {
color: var(--color-error) !important;
// Override previous values
&::-moz-progress-bar {
background: var(--color-error) !important;
Expand Down

0 comments on commit d6b87ef

Please sign in to comment.