diff --git a/packages/components/config/src/defaultConfig.ts b/packages/components/config/src/defaultConfig.ts index bf5298d67..12a842340 100644 --- a/packages/components/config/src/defaultConfig.ts +++ b/packages/components/config/src/defaultConfig.ts @@ -232,6 +232,10 @@ export const defaultConfig: GlobalConfig = { strokeLinecap: 'round', size: 'md', format: (percent: number) => percent + '%', + icon: { + success: 'check', + exception: 'close', + }, }, radio: { size: 'md', diff --git a/packages/components/config/src/types.ts b/packages/components/config/src/types.ts index 51031f449..8f1aeca34 100644 --- a/packages/components/config/src/types.ts +++ b/packages/components/config/src/types.ts @@ -365,10 +365,8 @@ export interface PopoverConfig { export interface ProgressConfig { size: ProgressSize format: ProgressFormat - defaultCircleStrokeWidth?: string | number - strokeWidth?: string | number strokeLinecap: 'round' | 'square' - icon?: Partial + icon: Partial } export interface RadioConfig { diff --git a/packages/components/progress/__tests__/progress.spec.ts b/packages/components/progress/__tests__/progress.spec.ts index b17dc4bb7..328acf871 100644 --- a/packages/components/progress/__tests__/progress.spec.ts +++ b/packages/components/progress/__tests__/progress.spec.ts @@ -28,6 +28,9 @@ describe('Progress', () => { await wrapper.setProps({ percent: 50 }) expect(wrapper.text()).toBe('50%') + await wrapper.setProps({ percent: 60.7 }) + expect(wrapper.text()).toBe('60.7%') + await wrapper.setProps({ percent: 100 }) expect(wrapper.text()).toBe('') }) diff --git a/packages/components/progress/demo/Round.vue b/packages/components/progress/demo/Round.vue index 656c6fe3e..5905e929b 100644 --- a/packages/components/progress/demo/Round.vue +++ b/packages/components/progress/demo/Round.vue @@ -1,11 +1,18 @@ - + diff --git a/packages/components/progress/docs/Api.zh.md b/packages/components/progress/docs/Api.zh.md index b09c6d1de..fd0015692 100644 --- a/packages/components/progress/docs/Api.zh.md +++ b/packages/components/progress/docs/Api.zh.md @@ -16,14 +16,14 @@ | `trailColor` | 未完成的分段的颜色 | `string` | - | - | - | | `strokeColor` | 进度条的色彩 | `string` | - | - | - | | `strokeLinecap` | 进度条的样式 | `'round' \| 'square'` | `'round'` | ✅ | `seer` 主题默认为 `'square'` | -| `icons` | 进度条状态图标 | `{ success: string \| VNode, exception: string \| VNode }` | - | ✅ | - | +| `icons` | 进度条状态图标 | `{ success: string \| VNode, exception: string \| VNode }` | `{success: 'check', exception: 'close'}` | ✅ | - | `type="line"` | 名称 | 说明 | 类型 | 默认值 | 全局配置 | 备注 | | --- | --- | --- | --- | --- | --- | | `size` | 进度条尺寸 | `lg \| 'md' \| 'sm'` | `'md'` | ✅ | - | -| `strokeColor` | 进度条的色彩,传入 object 时为渐变 | `string` \| { from: string; to: string; direction: string } | - | - | - | +| `strokeColor` | 进度条的色彩,传入 object 时为渐变 | `string` \| `{ from: string; to: string; direction: string }` | - | - | - | | `strokeWidth` | 进度条线的宽度,单位 px | `number` | 10 | - | - | `type="circle"` @@ -31,7 +31,7 @@ | 名称 | 说明 | 类型 | 默认值 | 全局配置 | 备注 | | --- | --- | --- | --- | --- | --- | | `width` | 圆形进度条画布宽度,单位 px | `number` | 132 | - | - | -| `strokeColor` | 圆形进度条的色彩,传入 object 时为渐变 | `string \| object` | - | - | - | +| `strokeColor` | 圆形进度条的色彩,传入 object 时为渐变 | `string` \| `{ from: string; to: string; direction: string }` | - | - | - | | `strokeWidth` | 圆形进度条线的宽度,单位是进度条画布宽度的百分比 | `number` | 6 | - | - | `type="dashboard"` diff --git a/packages/components/progress/src/Circle.tsx b/packages/components/progress/src/Circle.tsx index 293264a1d..81ff51f40 100644 --- a/packages/components/progress/src/Circle.tsx +++ b/packages/components/progress/src/Circle.tsx @@ -5,16 +5,15 @@ * found in the LICENSE file at https://github.com/IDuxFE/idux/blob/main/LICENSE */ -import { ComputedRef, computed, defineComponent, inject, ref } from 'vue' +import { ComputedRef, computed, defineComponent, inject } from 'vue' import { isObject } from 'lodash-es' import { convertNumber, uniqueId } from '@idux/cdk/utils' import ProgressInfo from './ProgressInfo' -import { useProps } from './composables/useProps' import { progressContext } from './tokens' -import { ConvertProgressSuccess, ProgressGapPositionType, ProgressProps, StringGradients } from './types' +import { ProgressGapPositionType, ProgressProps, StringGradients } from './types' import { handleCircleGradient } from './util' export interface CalcSharedProperties { @@ -31,48 +30,46 @@ const defaultStrokeWidth = 6 export default defineComponent({ name: 'IxProgressCircle', - setup() { - const { props, config, mergedPrefixCls, percent, formattedSuccess } = inject(progressContext)! + setup(_, { slots }) { + const { props, mergedPrefixCls, mergedStrokeLinecap, percent, successPercent } = inject(progressContext)! const circleMergedPrefixCls = computed(() => `${mergedPrefixCls.value}-circle`) - const computedProps = useProps(props, config) - const strokeWidth = computed(() => - convertNumber(computedProps.value.strokeWidth ?? config.defaultCircleStrokeWidth, defaultStrokeWidth), - ) - const isGradient = computed(() => isObject(computedProps.value.strokeColor)) - const linearGradientId = ref(`ix-progress-gradient-${uniqueId()}`) + const strokeWidth = computed(() => convertNumber(props.strokeWidth, defaultStrokeWidth)) + const isGradient = computed(() => isObject(props.strokeColor)) + const linearGradientId = computed(() => `${mergedPrefixCls.value}-gradient-${uniqueId()}`) + const calcSharedProperties = computed(() => { - const isCircle = computedProps.value.type === 'circle' + const isCircle = props.type === 'circle' const radius = 50 - strokeWidth.value / 2 return { isGradient: isGradient.value, percent: percent.value, linearGradientId: linearGradientId.value, radius, - gapPosition: computedProps.value.gapPosition ?? (isCircle ? 'top' : 'bottom'), + gapPosition: props.gapPosition ?? (isCircle ? 'top' : 'bottom'), len: Math.PI * 2 * radius, - gapDegree: convertNumber(computedProps.value.gapDegree ?? (isCircle ? 0 : 75)), + gapDegree: convertNumber(props.gapDegree ?? (isCircle ? 0 : 75)), } }) const circleGradient = computed(() => { - return isGradient.value ? handleCircleGradient(computedProps.value.strokeColor as StringGradients) : [] + return isGradient.value ? handleCircleGradient(props.strokeColor as StringGradients) : [] }) const pathString = usePathString(calcSharedProperties) const trailPathStyle = useTrailPathStyle(calcSharedProperties) - const strokePath = useCirclePath(calcSharedProperties, computedProps.value, percent, formattedSuccess) + const strokePath = useCirclePath(calcSharedProperties, circleMergedPrefixCls, props, percent, successPercent) const trailPathAttr = computed(() => ({ - stroke: computedProps.value.trailColor ?? '#f5f5f5', + stroke: props.trailColor ?? '#f5f5f5', 'fill-opacity': '0', - 'stroke-linecap': computedProps.value.strokeLinecap, + 'stroke-linecap': mergedStrokeLinecap.value, 'stroke-width': strokeWidth.value, d: pathString.value, })) const strokePathAttr = computed(() => ({ 'fill-opacity': '0', - 'stroke-linecap': computedProps.value.strokeLinecap, - 'stroke-width': computedProps.value.percent ? strokeWidth.value : 0, + 'stroke-linecap': mergedStrokeLinecap.value, + 'stroke-width': percent.value ? strokeWidth.value : 0, d: pathString.value, })) @@ -85,9 +82,9 @@ export default defineComponent({ } }) const circleStyle = computed(() => ({ - width: computedProps.value.width && `${computedProps.value.width}px`, - height: computedProps.value.width && `${computedProps.value.width}px`, - fontSize: computedProps.value.width && `${convertNumber(computedProps.value.width) * 0.15 + 6}px`, + width: props.width && `${props.width}px`, + height: props.width && `${props.width}px`, + fontSize: props.width && `${convertNumber(props.width) * 0.15 + 6}px`, })) const renderDefs = () => { @@ -127,7 +124,7 @@ export default defineComponent({ > {renderStrokePath()} - + ) }, @@ -184,15 +181,14 @@ function useTrailPathStyle(calcSharedProperties: ComputedRef, + circleMergedPrefixCls: ComputedRef, props: ProgressProps, percent: ComputedRef, - success: ComputedRef, + successPercent: ComputedRef, ) { return computed(() => { - const successPercent = success.value.percent - const { gapDegree, len, isGradient, linearGradientId } = calcSharedProperties.value - const strokeProgress = successPercent > 0 ? [successPercent, percent.value] : [percent.value] + const strokeProgress = successPercent.value > 0 ? [successPercent.value, percent.value] : [percent.value] const successColor = props.success?.strokeColor return strokeProgress @@ -201,8 +197,8 @@ function useCirclePath( return { stroke: isGradient && !hasSuccessPercent ? `url(#${linearGradientId})` : undefined, strokeClasses: [ - !isGradient && hasSuccessPercent ? 'ix-progress-circle-success' : '', - isGradient ? '' : 'ix-progress-circle-bg', + !isGradient && hasSuccessPercent ? `${circleMergedPrefixCls.value}-success` : '', + isGradient ? '' : `${circleMergedPrefixCls.value}-bg`, ], strokePathStyle: { stroke: !isGradient ? (hasSuccessPercent ? successColor : (props.strokeColor as string)) : undefined, diff --git a/packages/components/progress/src/Line.tsx b/packages/components/progress/src/Line.tsx index 6add3b0f8..dfa1b576a 100644 --- a/packages/components/progress/src/Line.tsx +++ b/packages/components/progress/src/Line.tsx @@ -10,57 +10,53 @@ import { computed, defineComponent, inject, ref } from 'vue' import { isObject } from 'lodash-es' import ProgressInfo from './ProgressInfo' -import { useProps } from './composables/useProps' import { progressContext } from './tokens' import { handleGradient } from './util' export default defineComponent({ name: 'IxProgressLine', - setup() { - const { props, config, mergedPrefixCls, percent, formattedSuccess } = inject(progressContext)! - const computedProps = useProps(props, config) + setup(_, { slots }) { + const { props, mergedPrefixCls, mergedSize, mergedStrokeLinecap, percent, successPercent } = + inject(progressContext)! + const lineMergedPrefixCls = computed(() => `${mergedPrefixCls.value}-line`) const elementRef = ref() - const lineClasses = computed(() => { + const classes = computed(() => { const prefixCls = lineMergedPrefixCls.value return { [prefixCls]: true, - [`${prefixCls}-${computedProps.value.size}`]: true, - [`${prefixCls}-round`]: computedProps.value.strokeLinecap === 'round', + [`${prefixCls}-${mergedSize.value}`]: true, + [`${prefixCls}-round`]: mergedStrokeLinecap.value === 'round', } }) const innerStyle = computed(() => ({ - background: computedProps.value.trailColor ?? '', + background: props.trailColor, })) const successStyle = computed(() => ({ - height: computedProps.value.strokeWidth && `${computedProps.value.strokeWidth}px`, - width: `${formattedSuccess.value.percent ?? 0}%`, - background: formattedSuccess.value.strokeColor ?? '', + height: `${props.strokeWidth}px`, + width: `${successPercent.value}%`, + background: props.success?.strokeColor, })) const bgStyle = computed(() => ({ - height: computedProps.value.strokeWidth && `${computedProps.value.strokeWidth}px`, + height: `${props.strokeWidth}px`, width: `${percent.value}%`, - background: isObject(computedProps.value.strokeColor) - ? handleGradient(computedProps.value.strokeColor, elementRef.value) - : computedProps.value.strokeColor ?? '', + background: isObject(props.strokeColor) ? handleGradient(props.strokeColor, elementRef.value) : props.strokeColor, })) return () => { const prefixCls = lineMergedPrefixCls.value return ( -
+
- {computedProps.value.success?.percent && ( -
- )} + {!!successPercent.value &&
}
- +
) } diff --git a/packages/components/progress/src/Progress.tsx b/packages/components/progress/src/Progress.tsx index 373474c2c..7edc2eb1a 100644 --- a/packages/components/progress/src/Progress.tsx +++ b/packages/components/progress/src/Progress.tsx @@ -11,10 +11,9 @@ import { useGlobalConfig } from '@idux/components/config' import Circle from './Circle' import Line from './Line' -import { useStatus } from './composables/useStatus' import { progressContext } from './tokens' -import { progressProps } from './types' -import { convertPercent } from './util' +import { progressProps, progressStatus } from './types' +import { convertPercent, fullPercent } from './util' export default defineComponent({ name: 'IxProgress', @@ -25,9 +24,20 @@ export default defineComponent({ const mergedPrefixCls = computed(() => `${common.prefixCls}-progress`) const percent = computed(() => convertPercent(props.percent)) - const formattedSuccess = computed(() => ({ ...props.success, percent: convertPercent(props.success?.percent) })) + const successPercent = computed(() => convertPercent(props.success?.percent)) + const mergedSize = computed(() => props.size ?? config.size) + const mergedStrokeLinecap = computed(() => props.strokeLinecap ?? config.strokeLinecap) - const status = useStatus(props, percent, formattedSuccess) + const status = computed(() => { + if ( + !progressStatus.includes(props.status!) && + (percent.value >= fullPercent || successPercent.value >= fullPercent) + ) { + return 'success' + } + + return props.status ?? 'normal' + }) const classes = computed(() => { const prefixCls = mergedPrefixCls.value @@ -40,16 +50,17 @@ export default defineComponent({ provide(progressContext, { props, config, - slots, mergedPrefixCls, + mergedSize, + mergedStrokeLinecap, percent, - formattedSuccess, + successPercent, status, }) return () => { const ProgressComponent = props.type === 'line' ? Line : Circle - return + return } }, }) diff --git a/packages/components/progress/src/ProgressInfo.tsx b/packages/components/progress/src/ProgressInfo.tsx index b70930343..39d1a2587 100644 --- a/packages/components/progress/src/ProgressInfo.tsx +++ b/packages/components/progress/src/ProgressInfo.tsx @@ -5,28 +5,30 @@ * found in the LICENSE file at https://github.com/IDuxFE/idux/blob/main/LICENSE */ -import { type VNode, defineComponent, inject } from 'vue' +import { type VNode, computed, defineComponent, inject } from 'vue' -import { isString } from 'lodash-es' +import { isFunction, isString } from 'lodash-es' import { IxIcon } from '@idux/components/icon' -import { useIcons } from './composables/useIcons' -import { useInfo } from './composables/useInfo' import { progressContext } from './tokens' +import { fullPercent } from './util' export default defineComponent({ - setup() { - const { props, config, slots, mergedPrefixCls, status, percent, formattedSuccess } = inject(progressContext)! - const { formattedText, showSuccessIcon, showExceptionIcon, showFormat } = useInfo( - props, - config, - status, - percent, - formattedSuccess, + setup(_, { slots }) { + const { props, config, mergedPrefixCls, status, percent, successPercent } = inject(progressContext)! + + const formatFn = computed(() => props.format ?? config.format) + const formattedText = computed(() => formatFn.value(percent.value, successPercent.value)) + + const showSuccessIcon = computed( + () => status.value === 'success' || (status.value === 'normal' && percent.value === fullPercent), ) + const showExceptionIcon = computed(() => status.value === 'exception') + const showFormat = computed(() => isFunction(props.format) || !(showSuccessIcon.value || showExceptionIcon.value)) - const icons = useIcons(props, config) + const mergedIconSuccess = computed(() => props.icons?.success ?? config.icon.success) + const mergedIconException = computed(() => props.icons?.exception ?? config.icon.exception) const renderInfo = () => { if (showFormat.value) { @@ -35,12 +37,12 @@ export default defineComponent({ const prefixCls = mergedPrefixCls.value - if (showSuccessIcon.value) { - return renderIcon(icons.value.success, `${prefixCls}-success-icon`) + if (showSuccessIcon.value && mergedIconSuccess.value) { + return renderIcon(mergedIconSuccess.value, `${prefixCls}-success-icon`) } - if (showExceptionIcon.value) { - return renderIcon(icons.value.exception, `${prefixCls}-exception-icon`) + if (showExceptionIcon.value && mergedIconException.value) { + return renderIcon(mergedIconException.value, `${prefixCls}-exception-icon`) } return null @@ -53,7 +55,7 @@ export default defineComponent({ const slot = slots.format ?? slots.default return (
- {slot ? slot({ percent: percent.value, successPercent: formattedSuccess.value.percent }) : renderInfo()} + {slot ? slot({ percent: percent.value, successPercent: successPercent.value }) : renderInfo()}
) } diff --git a/packages/components/progress/src/composables/useIcons.ts b/packages/components/progress/src/composables/useIcons.ts deleted file mode 100644 index ac3ffb94c..000000000 --- a/packages/components/progress/src/composables/useIcons.ts +++ /dev/null @@ -1,23 +0,0 @@ -/** - * @license - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://github.com/IDuxFE/idux/blob/main/LICENSE - */ - -import type { ProgressIcons, ProgressProps } from '../types' -import type { ProgressConfig } from '@idux/components/config' - -import { type ComputedRef, computed } from 'vue' - -const defaultIcons: ProgressIcons = { - success: 'check', - exception: 'close', -} - -export function useIcons(props: ProgressProps, config: ProgressConfig): ComputedRef { - return computed(() => ({ - success: props.icons?.success ?? config.icon?.success ?? defaultIcons.success, - exception: props.icons?.exception ?? config.icon?.exception ?? defaultIcons.exception, - })) -} diff --git a/packages/components/progress/src/composables/useInfo.ts b/packages/components/progress/src/composables/useInfo.ts deleted file mode 100644 index 65d693708..000000000 --- a/packages/components/progress/src/composables/useInfo.ts +++ /dev/null @@ -1,44 +0,0 @@ -/** - * @license - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://github.com/IDuxFE/idux/blob/main/LICENSE - */ - -import type { ConvertProgressSuccess, ProgressProps, ProgressStatus } from '../types' -import type { ProgressConfig } from '@idux/components/config' - -import { type ComputedRef, type VNodeChild, computed } from 'vue' - -import { isFunction } from 'lodash-es' - -import { fullPercent } from '../util' - -export const useInfo = ( - props: ProgressProps, - config: ProgressConfig, - progressStatus: ComputedRef, - percent: ComputedRef, - success: ComputedRef, -): { - formattedText: ComputedRef - showFormat: ComputedRef - showSuccessIcon: ComputedRef - showExceptionIcon: ComputedRef -} => { - const formatFn = props.format ?? config.format - const formattedText = computed(() => formatFn(percent.value, success.value.percent)) - - const showSuccessIcon = computed( - () => progressStatus.value === 'success' || (progressStatus.value === 'normal' && percent.value === fullPercent), - ) - const showExceptionIcon = computed(() => progressStatus.value === 'exception') - const showFormat = computed(() => isFunction(props.format) || !(showSuccessIcon.value || showExceptionIcon.value)) - - return { - formattedText, - showFormat, - showSuccessIcon, - showExceptionIcon, - } -} diff --git a/packages/components/progress/src/composables/useProps.ts b/packages/components/progress/src/composables/useProps.ts deleted file mode 100644 index b99cb6645..000000000 --- a/packages/components/progress/src/composables/useProps.ts +++ /dev/null @@ -1,20 +0,0 @@ -/** - * @license - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://github.com/IDuxFE/idux/blob/main/LICENSE - */ - -import type { ProgressProps } from '../types' -import type { ProgressConfig } from '@idux/components/config' - -import { type ComputedRef, computed } from 'vue' - -export function useProps(props: ProgressProps, config: ProgressConfig): ComputedRef { - return computed(() => ({ - ...props, - size: props.size ?? config.size, - strokeWidth: props.strokeWidth ?? config.strokeWidth, - strokeLinecap: props.strokeLinecap ?? config.strokeLinecap, - })) -} diff --git a/packages/components/progress/src/composables/useStatus.ts b/packages/components/progress/src/composables/useStatus.ts deleted file mode 100644 index 1ad14e146..000000000 --- a/packages/components/progress/src/composables/useStatus.ts +++ /dev/null @@ -1,28 +0,0 @@ -/** - * @license - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://github.com/IDuxFE/idux/blob/main/LICENSE - */ - -import { type ComputedRef, computed } from 'vue' - -import { type ConvertProgressSuccess, type ProgressProps, type ProgressStatus, progressStatus } from '../types' -import { fullPercent } from '../util' - -export function useStatus( - props: ProgressProps, - percent: ComputedRef, - success: ComputedRef, -): ComputedRef { - return computed(() => { - if ( - !progressStatus.includes(props.status!) && - (percent.value >= fullPercent || success.value.percent >= fullPercent) - ) { - return 'success' - } - - return props.status ?? 'normal' - }) -} diff --git a/packages/components/progress/src/tokens.ts b/packages/components/progress/src/tokens.ts index a22e164d0..2e0287f64 100644 --- a/packages/components/progress/src/tokens.ts +++ b/packages/components/progress/src/tokens.ts @@ -5,18 +5,19 @@ * found in the LICENSE file at https://github.com/IDuxFE/idux/blob/main/LICENSE */ -import type { ConvertProgressSuccess, ProgressProps, ProgressStatus } from './types' +import type { ProgressProps, ProgressSize, ProgressStatus, ProgressStrokeLinecap } from './types' import type { ProgressConfig } from '@idux/components/config' -import type { ComputedRef, InjectionKey, Slots } from 'vue' +import type { ComputedRef, InjectionKey } from 'vue' interface ProgressContext { config: Readonly mergedPrefixCls: ComputedRef + mergedSize: ComputedRef + mergedStrokeLinecap: ComputedRef props: ProgressProps - slots: Slots status: ComputedRef + successPercent: ComputedRef percent: ComputedRef - formattedSuccess: ComputedRef } export const progressContext: InjectionKey = Symbol('progressContext') diff --git a/packages/components/progress/src/types.ts b/packages/components/progress/src/types.ts index 1350c2c9f..6c45b6bd4 100644 --- a/packages/components/progress/src/types.ts +++ b/packages/components/progress/src/types.ts @@ -19,7 +19,7 @@ export type FromToGradients = { from: string; to: string } export type ProgressGradient = { direction?: string } & (StringGradients | FromToGradients) export interface ProgressSuccess { - percent?: number | string + percent?: number strokeColor?: string } @@ -41,7 +41,7 @@ export const progressProps = { }, format: Function as PropType, percent: { - type: [String, Number] as PropType, + type: Number, default: 0, }, status: String as PropType, @@ -53,11 +53,11 @@ export const progressProps = { trailColor: String, strokeColor: [String, Object] as PropType, strokeLinecap: String as PropType, - strokeWidth: [String, Number] as PropType, - gapDegree: [String, Number] as PropType, + strokeWidth: Number, + gapDegree: Number, gapPosition: String as PropType, width: { - type: [String, Number] as PropType, + type: Number, default: 132, }, size: String as PropType, diff --git a/packages/components/progress/src/util.ts b/packages/components/progress/src/util.ts index 17cd385aa..f0c836b45 100644 --- a/packages/components/progress/src/util.ts +++ b/packages/components/progress/src/util.ts @@ -9,14 +9,14 @@ import { ProgressGradient, StringGradients } from './types' export const fullPercent = 100 -export function convertPercent(percent: number | string | undefined): number { +export function convertPercent(percent: number | undefined): number { if (!percent || percent < 0) { return 0 } if (percent > fullPercent) { return fullPercent } - return parseInt(percent as string, 10) + return percent } interface SortGradientResult { diff --git a/packages/components/progress/style/index.less b/packages/components/progress/style/index.less index 610cfd134..b25ef7fd3 100644 --- a/packages/components/progress/style/index.less +++ b/packages/components/progress/style/index.less @@ -85,6 +85,7 @@ } .@{progress-prefix}-active &-bg { + position: relative; background-color: @progress-active-background-color; &::before {