Skip to content

Commit

Permalink
Merge pull request #7 from wind13/status-icon
Browse files Browse the repository at this point in the history
refactor(Progress): #501 Done status icon and refine code.
  • Loading branch information
wind13 authored Dec 21, 2020
2 parents 769752b + d697272 commit ae37cf2
Show file tree
Hide file tree
Showing 5 changed files with 214 additions and 171 deletions.
61 changes: 24 additions & 37 deletions packages/element3/src/components/Progress/src/Progress.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,27 @@
<div class="el-progress-bar__inner" :style="barStyle"></div>
</div>
</div>
<div class="el-progress__text">{{ content }}</div>
<div class="el-progress__text">
<template v-if="!status">{{ content }}</template>
<i v-else :class="iconClass"></i>
</div>
<div data-testid="temptest" class="temptest">{{ '' }}</div>
</div>
</template>

<script>
import { computed, defineComponent, isRef, toRefs } from 'vue'
import { computed, defineComponent, toRefs } from 'vue'
import { isArray, isFunction, isString } from '../../../utils/types'
import { props, statusValid } from './props'
import {
props,
statusValid,
autoFixPercentage,
getRefValue,
toPercentageColors,
sortByPercentage,
getColorsIndex,
STATUS_SETTING
} from './props'
export default defineComponent({
name: 'ElProgress',
Expand All @@ -23,43 +35,11 @@ export default defineComponent({
const barStyle = useBarStyle(percentage, color)
const content = useContent(format, percentage)
const statusClass = useStatusClass(status)
return { barStyle, content, statusClass }
const iconClass = useIconClass(status)
return { barStyle, content, statusClass, iconClass }
}
})
export function getColorsIndex(colors, percent) {
const i = colors.findIndex((c) => percent < c.percentage)
return i < 0 ? colors.length - 1 : i
}
export function getRefValue(ref) {
return isRef(ref) ? ref.value : ref
}
export function sortByPercentage(pre, next) {
return pre.percentage - next.percentage
}
export function toPercentageColors(colors) {
const span = 100 / colors.length
return colors.map((color, i) => {
if (isString(color)) {
return { color, percentage: span * (i + 1) }
}
return color
})
}
export function autoFixPercentage(percentage) {
if (percentage < 0) {
return 0
}
if (percentage > 100) {
return 100
}
return percentage
}
const useBarStyle = (percentage, color) => {
return computed(() => {
const pv = autoFixPercentage(getRefValue(percentage))
Expand Down Expand Up @@ -98,6 +78,13 @@ const useStatusClass = (status) => {
return st && statusValid(st) ? `is-${st}` : ''
})
}
const useIconClass = (status) => {
return computed(() => {
const st = getRefValue(status)
return STATUS_SETTING[st] || ''
})
}
</script>

<style></style>
46 changes: 43 additions & 3 deletions packages/element3/src/components/Progress/src/props.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import { isNumber } from '../../../utils/types'
import { isRef } from 'vue'
import { isNumber, isString } from '../../../utils/types'

export const STATUS_SETTING = {
success: 'el-icon-circle-check',
warning: 'el-icon-warning',
exception: 'el-icon-circle-close'
}
export const STATUSES = Object.keys(STATUS_SETTING)

export const statusValid = (val) => STATUSES.includes(val)
export const percentageValid = (val) => isNumber(val) && val >= 0 && val <= 100
export const statuses = ['success', 'exception', 'warning']
export const statusValid = (val) => statuses.includes(val)

export const props = {
percentage: {
Expand All @@ -18,3 +25,36 @@ export const props = {
},
color: { type: [String, Function, Array], default: '' }
}

export function getColorsIndex(colors, percent) {
const i = colors.findIndex((c) => percent < c.percentage)
return i < 0 ? colors.length - 1 : i
}

export function getRefValue(ref) {
return isRef(ref) ? ref.value : ref
}

export function sortByPercentage(pre, next) {
return pre.percentage - next.percentage
}

export function toPercentageColors(colors) {
const span = 100 / colors.length
return colors.map((color, i) => {
if (isString(color)) {
return { color, percentage: span * (i + 1) }
}
return color
})
}

export function autoFixPercentage(percentage) {
if (percentage < 0) {
return 0
}
if (percentage > 100) {
return 100
}
return percentage
}
142 changes: 12 additions & 130 deletions packages/element3/src/components/Progress/tests/Progress.spec.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { mount } from '@vue/test-utils'
import Progress from '../src/Progress.vue'
import { sortByPercentage } from '../src/props'
import {
getColorsIndex,
getRefValue,
sortByPercentage,
toPercentageColors,
autoFixPercentage
} from '../src/Progress.vue'
import Color from '../../../../packages/color-picker/src/color'
import { isRef, toRefs, reactive } from 'vue'
assertHasClass,
assertNotHasClass,
assertExistsElem,
assertSetPercentage,
assertSetBgColor,
assertContainText,
assertNotContainStyle
} from './test-helper'

describe('Progress.vue', () => {
it('should create default Progress component and HTML structure', () => {
Expand Down Expand Up @@ -41,12 +42,6 @@ describe('Progress.vue', () => {
assertSetPercentage(wrapper, 28)
})

it('fix percentage value', () => {
expect(autoFixPercentage(-2)).toBe(0)
expect(autoFixPercentage(129)).toBe(100)
expect(autoFixPercentage(29)).toBe(29)
})

it('percentage validator', async () => {
const percentage = 158
const wrapper = mount(Progress, {
Expand Down Expand Up @@ -110,70 +105,6 @@ describe('Progress.vue', () => {
assertSetBgColor(wrapper, color(p3))
})

it('get index of percentage in array', () => {
const colors = [
{ color: '#1989fa', percentage: 80 },
{ color: '#f56c6c', percentage: 20 },
{ color: '#6f7ad3', percentage: 100 },
{ color: '#5cb87a', percentage: 60 },
{ color: '#e6a23c', percentage: 40 }
]
colors.sort(sortByPercentage)
expect(getColorsIndex(colors, 0)).toBe(0)
expect(getColorsIndex(colors, 12)).toBe(0)
expect(getColorsIndex(colors, 20)).toBe(1)
expect(getColorsIndex(colors, 32)).toBe(1)
expect(getColorsIndex(colors, 42)).toBe(2)
expect(getColorsIndex(colors, 62)).toBe(3)
expect(getColorsIndex(colors, 82)).toBe(4)
expect(getColorsIndex(colors, 100)).toBe(4)
})

it('should get ref value correct', () => {
expect(isRef(undefined)).toBeFalsy()
expect(isRef(null)).toBeFalsy()
expect(isRef(0)).toBeFalsy()
expect(isRef('')).toBeFalsy()
expect(isRef(false)).toBeFalsy()
expect(isRef(true)).toBeFalsy()
const props = reactive({
percentage: 0,
color: ['#336699', '#339966', '#996633']
})
const { percentage, color } = toRefs(props)
const pv = getRefValue(percentage)
expect(pv).toBe(props.percentage)
const cv = color.value
expect(cv).toEqual(props.color)
})

it('should map to percentage colors correct', () => {
const colors = ['#336699', '#339966', '#996633', '#663399']
const rs = toPercentageColors(colors)
expect(rs.length).toBe(4)
expect(rs[0].color).toBe(colors[0])
expect(rs[0].percentage).toBe(25)
expect(rs[1].percentage).toBe(50)
expect(rs[2].percentage).toBe(75)
expect(rs[3].percentage).toBe(100)

const colorObjs = [
{ color: '#1989fa', percentage: 80 },
{ color: '#6f7ad3', percentage: 100 },
{ color: '#5cb87a', percentage: 60 },
{ color: '#f56c6c', percentage: 20 },
{ color: '#e6a23c', percentage: 40 }
]
const objs = toPercentageColors(colorObjs)
expect(objs.length).toBe(5)
expect(objs[0].color).toBe(colorObjs[0].color)
expect(objs[0].percentage).toBe(80)
expect(objs[1].percentage).toBe(100)
expect(objs[2].percentage).toBe(60)
expect(objs[3].percentage).toBe(20)
expect(objs[4].percentage).toBe(40)
})

it('color string array', async () => {
const colors = ['#336699', '#339966', '#996633']
const percentage = 15
Expand Down Expand Up @@ -220,65 +151,16 @@ describe('Progress.vue', () => {
const props = { percentage, status }
const wrapper = mount(Progress, { props })
assertHasClass(wrapper, 'is-success')
assertExistsElem(wrapper, '.el-progress__text > i.el-icon-circle-check')
await wrapper.setProps({ status: 'exception' })
assertHasClass(wrapper, 'is-exception')
assertExistsElem(wrapper, '.el-progress__text > i.el-icon-circle-close')
await wrapper.setProps({ status: 'warning' })
assertHasClass(wrapper, 'is-warning')
assertExistsElem(wrapper, '.el-progress__text > i.el-icon-warning')

await wrapper.setProps({ status: 'error' })
assertNotHasClass(wrapper, 'is-error')
})
})
})

function assertSetBgColor(wrapper, color) {
const rgb = fromHexToRgb(color)
assertContainStyle(
wrapper,
'.el-progress-bar__inner',
`background-color: ${rgb};`
)
}

function fromHexToRgb(hex) {
const c = new Color()
c.fromString(hex)
const rgb = c.toRgb()
return `rgb(${rgb.r}, ${rgb.g}, ${rgb.b})`
}

function assertSetPercentage(wrapper, percentage) {
assertContainText(wrapper, '.el-progress__text', `${percentage}%`)
assertContainStyle(
wrapper,
'.el-progress-bar__inner',
`width: ${percentage}%;`
)
}

function assertContainStyle(wrapper, selector, strStyle) {
const elem = wrapper.find(selector)
expect(elem.attributes().style).toBeDefined()
expect(elem.attributes().style).toContain(strStyle)
}

function assertNotContainStyle(wrapper, selector, strStyle) {
const elem = wrapper.find(selector)
expect(elem.attributes().style).not.toContain(strStyle)
}

function assertContainText(wrapper, selector, text) {
expect(wrapper.find(selector).text()).toContain(text)
}

function assertHasClass(elem, className) {
expect(elem.classes().includes(className)).toBeTruthy()
}

function assertNotHasClass(elem, className) {
expect(elem.classes().includes(className)).toBeFalsy()
}

function assertExistsElem(wrapper, selector) {
expect(wrapper.find(selector).exists()).toBeTruthy()
}
Loading

0 comments on commit ae37cf2

Please sign in to comment.