Skip to content

Commit

Permalink
feat(progress): support linear gradient color when mode is circle
Browse files Browse the repository at this point in the history
  • Loading branch information
binbin authored and binbin committed Sep 15, 2023
1 parent 499cd46 commit d215967
Show file tree
Hide file tree
Showing 8 changed files with 117 additions and 40 deletions.
38 changes: 33 additions & 5 deletions packages/varlet-ui/src/progress/Progress.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
:style="{ height: toSizeUnit(lineWidth), background: trackColor }"
>
<div v-if="indeterminate" :class="classes([indeterminate, n('linear-indeterminate')])">
<div :class="classes(n(`linear--${type}`))" :style="{ background: color }"></div>
<div :class="classes(n(`linear--${type}`))" :style="{ background: color }"></div>
<div :class="classes(n(`linear--${type}`))" :style="{ background: progressColor }"></div>
<div :class="classes(n(`linear--${type}`))" :style="{ background: progressColor }"></div>
</div>
<div
v-else
:class="classes(n('linear-certain'), n(`linear--${type}`), [ripple, n('linear-ripple')])"
:style="{ background: color, width: linearProps.width }"
:style="{ background: progressColor, width: linearProps.width }"
></div>
</div>
<div :class="classes(n('linear-label'), [labelClass, labelClass])" v-if="label">
Expand All @@ -28,6 +28,16 @@
:style="{ width: toSizeUnit(size), height: toSizeUnit(size) }"
>
<svg :class="n('circle-svg')" :style="{ transform: `rotate(${rotate - 90}deg)` }" :viewBox="circleProps.viewBox">
<defs v-if="typeof color === 'object' && color != null">
<linearGradient x1="100%" y1="0%" x2="0%" y2="0%" :id="id">
<stop
v-for="(progress, idx) in linearGradientProgress"
:key="idx"
:offset="progress"
:stop-color="color[progress]"
></stop>
</linearGradient>
</defs>
<circle
v-if="track"
:class="n('circle-background')"
Expand All @@ -51,7 +61,7 @@
:stroke-dasharray="CIRCUMFERENCE"
:stroke-dashoffset="circleProps.strokeOffset"
:style="{
stroke: color,
stroke: progressColor,
}"
></circle>
</svg>
Expand All @@ -68,20 +78,22 @@
<script lang="ts">
import { defineComponent, computed } from 'vue'
import { props } from './props'
import { toNumber } from '@varlet/shared'
import { isObject, toNumber } from '@varlet/shared'
import { toSizeUnit, toPxNum } from '../utils/elements'
import { createNamespace } from '../utils/components'
const ONE_HUNDRED = 100
const RADIUS = 20
const CIRCUMFERENCE = 2 * Math.PI * RADIUS
let uid = 0
const { name, n, classes } = createNamespace('progress')
export default defineComponent({
name,
props,
setup(props) {
const id = `var-progress-${uid++}`
const linearProps = computed(() => {
const value = toNumber(props.value)
const width = value > ONE_HUNDRED ? ONE_HUNDRED : value
Expand All @@ -92,6 +104,7 @@ export default defineComponent({
roundValue: `${roundValue}%`,
}
})
const circleProps = computed(() => {
const { size, lineWidth, value } = props
Expand All @@ -109,11 +122,26 @@ export default defineComponent({
}
})
const progressColor = computed(() => {
if (isObject(props.color)) {
return `url(#${id})`
}
return props.color
})
const linearGradientProgress = computed(() =>
Object.keys(props.color!).sort((a, b) => parseFloat(a) - parseFloat(b))
)
return {
id,
linearProps,
CIRCUMFERENCE,
RADIUS,
circleProps,
progressColor,
linearGradientProgress,
n,
classes,
toSizeUnit,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`test progress component props > test circle progress color 1`] = `
"<div class=\\"var-progress\\">
<!--v-if-->
<div class=\\"var-progress__circle\\" style=\\"width: 40px; height: 40px;\\"><svg class=\\"var-progress__circle-svg\\" style=\\"transform: rotate(-90deg);\\" viewBox=\\"0 0 44.44444444444444 44.44444444444444\\">
<defs>
<linearGradient x1=\\"100%\\" y1=\\"0%\\" x2=\\"0%\\" y2=\\"0%\\" id=\\"var-progress-10\\">
<stop offset=\\"0%\\" stop-color=\\"#3fecff\\"></stop>
<stop offset=\\"100%\\" stop-color=\\"#6149f6\\"></stop>
</linearGradient>
</defs>
<circle class=\\"var-progress__circle-background\\" cx=\\"50%\\" cy=\\"50%\\" r=\\"20\\" fill=\\"transparent\\" stroke-width=\\"4.444444444444445\\" stroke-dasharray=\\"125.66370614359172\\"></circle>
<circle class=\\"var-progress__circle-certain var-progress__circle--primary\\" cx=\\"50%\\" cy=\\"50%\\" r=\\"20\\" fill=\\"transparent\\" stroke-width=\\"4.444444444444445\\" stroke-dasharray=\\"125.66370614359172\\" stroke-dashoffset=\\"125.66370614359172\\" style=\\"stroke: url(#var-progress-10);\\"></circle>
</svg>
<!--v-if-->
</div>
</div>"
`;
17 changes: 16 additions & 1 deletion packages/varlet-ui/src/progress/__tests__/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ describe('test progress component props', () => {
wrapper.unmount()
})

test('test progress color', () => {
test('test linear progress color', () => {
const wrapper = mount(VarProgress, {
props: {
color: 'red',
Expand All @@ -64,6 +64,21 @@ describe('test progress component props', () => {
wrapper.unmount()
})

test('test circle progress color', () => {
const wrapper = mount(VarProgress, {
props: {
color: {
'0%': '#3fecff',
'100%': '#6149f6',
},
mode: 'circle',
},
})

expect(wrapper.html()).toMatchSnapshot()
wrapper.unmount()
})

test('test progress track-color', () => {
const wrapper = mount(VarProgress, {
props: {
Expand Down
61 changes: 33 additions & 28 deletions packages/varlet-ui/src/progress/docs/en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,21 @@ Display the current progress of an operation flow.

```html
<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
import { ref, onMounted, onUnmounted } from 'vue'
const value = ref(0)
const interval = ref(0)
const value = ref(0)
const interval = ref(0)
onMounted(() => {
interval.value = window.setInterval(() => {
if (value.value >= 100) value.value = 0
else value.value += 20
}, 1000)
})
onMounted(() => {
interval.value = window.setInterval(() => {
if (value.value >= 100) value.value = 0
else value.value += 20
}, 1000)
})
onUnmounted(() => {
window.clearInterval(interval.value)
})
onUnmounted(() => {
window.clearInterval(interval.value)
})
</script>

<template>
Expand Down Expand Up @@ -52,25 +52,30 @@ Set the line width, progress bar color and track color through the attributes of

```html
<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
const value = ref(0)
const interval = ref(0)
onMounted(() => {
interval.value = window.setInterval(() => {
if (value.value >= 100) value.value = 0
else value.value += 20
}, 1000)
})
onUnmounted(() => {
window.clearInterval(interval.value)
})
import { ref, onMounted, onUnmounted } from 'vue'
const value = ref(0)
const interval = ref(0)
const gradientColor = {
'0%': '#3fecff',
'100%': '#6149f6',
}
onMounted(() => {
interval.value = window.setInterval(() => {
if (value.value >= 100) value.value = 0
else value.value += 20
}, 1000)
})
onUnmounted(() => {
window.clearInterval(interval.value)
})
</script>

<template>
<var-space :size="[20, 20]">
<var-progress mode="circle" :value="50" :size="60" :color="gradientColor" />
<var-progress mode="circle" :value="75" :size="60" :track="false" />
<var-progress mode="circle" label :value="value" :line-width="5" :size="60" />
<var-progress mode="circle" type="success" label :value="100" :line-width="5" :size="60">
Expand Down Expand Up @@ -108,7 +113,7 @@ Enable indeterminate animation through the `indeterminate` attribute when loadin
| `type` | Progress type, Can be set to `default` `primary` `info` `success` `warning` `danger` | _string_ | `primary` |
| `value` | Completion value | _string \| number_ | `0` |
| `line-width` | Width of the progress bar | _string \| number_ | `4` |
| `color` | Color of the progress bar | _string_ | `#005CAF` |
| `color` | Color of the progress bar | _string \| object_ | `#005CAF` |
| `track-color` | Color of the progress track | _string_ | `#d8d8d8` |
| `label` | Whether the label is visible or not | _boolean_ | `false` |
| `label-class` | Custom label class name | _string_ | `-` |
Expand Down
7 changes: 6 additions & 1 deletion packages/varlet-ui/src/progress/docs/zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ import { ref, onMounted, onUnmounted } from 'vue'
const value = ref(0)
const interval = ref(0)
const gradientColor = {
'0%': '#3fecff',
'100%': '#6149f6',
}
onMounted(() => {
interval.value = window.setInterval(() => {
Expand All @@ -71,6 +75,7 @@ onUnmounted(() => {

<template>
<var-space :size="[20, 20]">
<var-progress mode="circle" :value="50" :size="60" :color="gradientColor" />
<var-progress mode="circle" :value="75" :size="60" :track="false" />
<var-progress mode="circle" label :value="value" :line-width="5" :size="60" />
<var-progress mode="circle" type="success" label :value="100" :line-width="5" :size="60">
Expand Down Expand Up @@ -108,7 +113,7 @@ onUnmounted(() => {
| `type` | 类型,可选值为 `default` `primary` `info` `success` `warning` `danger` | _string_ | `primary` |
| `value` | `progress` 的进度 | _string \| number_ | `0` |
| `line-width` | `progress` 的线宽 | _string \| number_ | `4` |
| `color` | `progress` 的颜色 | _string_ | `#005CAF` |
| `color` | `progress` 的颜色 | _string \| object_ | `#005CAF` |
| `track-color` | `progress` 轨道的颜色 | _string_ | `#d8d8d8` |
| `label` | 是否显示 `label` | _boolean_ | `false` |
| `label-class` | 自定义 `label` 的类名 | _string_ | `-` |
Expand Down
11 changes: 8 additions & 3 deletions packages/varlet-ui/src/progress/example/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ import { pack, use } from './locale'
const value = ref(0)
const interval = ref(0)
const gradientColor = {
'0%': '#3fecff',
'100%': '#6149f6',
}
onMounted(() => {
interval.value = window.setInterval(() => {
Expand Down Expand Up @@ -41,9 +45,10 @@ onUnmounted(() => {

<app-type>{{ pack.circle }}</app-type>
<var-space :size="['8vmin', '8vmin']">
<var-progress mode="circle" :value="75" size="18vmin" :track="false" />
<var-progress mode="circle" label :value="value" line-width="5" size="18vmin" />
<var-progress mode="circle" type="success" label :value="100" line-width="5" size="18vmin"> success </var-progress>
<var-progress mode="circle" :value="50" size="16vmin" :color="gradientColor" />
<var-progress mode="circle" :value="75" size="16vmin" :track="false" />
<var-progress mode="circle" label :value="value" line-width="5" size="16vmin" />
<var-progress mode="circle" type="success" label :value="100" line-width="5" size="16vmin"> success </var-progress>
</var-space>

<app-type>{{ pack.indeterminateProgress }}</app-type>
Expand Down
2 changes: 1 addition & 1 deletion packages/varlet-ui/src/progress/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const props = {
type: [Number, String],
default: 4,
},
color: String,
color: [String, Object] as PropType<string | Record<string, string>>,
trackColor: String,
ripple: Boolean,
value: {
Expand Down
2 changes: 1 addition & 1 deletion packages/varlet-ui/types/progress.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export interface ProgressProps extends BasicAttributes {
type?: ProgressType
indeterminate?: boolean
lineWidth?: string | number
color?: string
color?: string | Record<string, string>
trackColor?: string
label?: boolean
labelClass?: string
Expand Down

0 comments on commit d215967

Please sign in to comment.