refactor(components): [switch] Simplify color handling (#8199)

1. Use CSS variables to set `(in)activeColor` in order not to modify DOM
2. Deprecate property `(in)activeColor` in favor of CSS variables
This commit is contained in:
Carter Li 2022-06-12 22:40:53 +08:00 committed by GitHub
parent 1702a20214
commit 1aa9d43129
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 54 additions and 43 deletions

View File

@ -9,7 +9,7 @@ Switch is used for switching between two opposing states.
## Basic usage
:::demo Bind `v-model` to a `Boolean` typed variable. The `active-color` and `inactive-color` attribute decides the background color in two states.
:::demo Bind `v-model` to a `Boolean` typed variable. The `--el-switch-on-color` and `--el-switch-off-color` CSS variables decides the background color in two states.
switch/basic
@ -95,9 +95,9 @@ switch/prevent-switching
| inactive-text | text displayed when in `off` state | string | — | — |
| active-value | switch value when in `on` state | boolean / string / number | — | true |
| inactive-value | switch value when in `off` state | boolean / string / number | — | false |
| active-color | background color when in `on` state | string | — | #409EFF |
| inactive-color | background color when in `off` state | string | — | #C0CCDA |
| border-color | border color of the switch | string | — | — |
| active-color | background color when in `on` state ( deprecated, use CSS var `--el-switch-on-color` instead ) | string | — | |
| inactive-color | background color when in `off` state ( deprecated, use CSS var `--el-switch-off-color` instead ) | string | — | |
| border-color | border color of the switch ( deprecated, use CSS var `--el-switch-border-color` instead ) | string | — | — |
| name | input name of Switch | string | — | — |
| validate-event | whether to trigger form validation | boolean | — | true |
| before-change | before-change hook before the switch state changes. If `false` is returned or a `Promise` is returned and then is rejected, will stop switching | function | — | — |

View File

@ -3,8 +3,7 @@
<el-switch
v-model="value2"
class="ml-2"
active-color="#13ce66"
inactive-color="#ff4949"
style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
/>
</template>

View File

@ -2,8 +2,7 @@
<el-tooltip :content="'Switch value: ' + value" placement="top">
<el-switch
v-model="value"
active-color="#13ce66"
inactive-color="#ff4949"
style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
active-value="100"
inactive-value="0"
/>

View File

@ -9,8 +9,7 @@
<el-switch
v-model="value2"
class="mb-2"
active-color="#13ce66"
inactive-color="#ff4949"
style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
active-text="Pay by month"
inactive-text="Pay by year"
/>
@ -25,8 +24,7 @@
v-model="value4"
class="ml-2"
inline-prompt
active-color="#13ce66"
inactive-color="#ff4949"
style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
active-text="Y"
inactive-text="N"
/>

View File

@ -26,8 +26,14 @@ describe('Switch.vue', () => {
},
})
const vm = wrapper.vm
expect(vm.$el.style.getPropertyValue('--el-switch-on-color')).toEqual(
'#0f0'
)
expect(vm.$el.style.getPropertyValue('--el-switch-off-color')).toEqual(
'#f00'
)
expect(vm.$el.classList.contains('is-checked')).false
const coreEl = vm.$el.querySelector('.el-switch__core')
expect(coreEl.style.backgroundColor).toEqual('rgb(255, 0, 0)')
expect(coreEl.style.width).toEqual('100px')
const leftLabelWrapper = wrapper.find('.el-switch__label--left span')
expect(leftLabelWrapper.text()).toEqual('off')
@ -63,8 +69,14 @@ describe('Switch.vue', () => {
},
})
const vm = wrapper.vm
expect(vm.$el.style.getPropertyValue('--el-switch-on-color')).toEqual(
'#0f0'
)
expect(vm.$el.style.getPropertyValue('--el-switch-off-color')).toEqual(
'#f00'
)
expect(vm.$el.classList.contains('is-checked')).false
const coreEl = vm.$el.querySelector('.el-switch__core')
expect(coreEl.style.backgroundColor).toEqual('rgb(255, 0, 0)')
expect(coreEl.style.width).toEqual('100px')
const leftLabelWrapper = wrapper.find('.el-switch__inner span')
expect(leftLabelWrapper.text()).toEqual('on')
@ -87,13 +99,11 @@ describe('Switch.vue', () => {
'el-switch': Switch,
},
template: `
<div>
<el-switch
v-model="value"
activeColor="#0f0"
inactiveColor="#f00">
</el-switch>
</div>
<el-switch
v-model="value"
activeColor="#0f0"
inactiveColor="#f00">
</el-switch>
`,
data() {
return {
@ -102,13 +112,19 @@ describe('Switch.vue', () => {
},
})
const vm = wrapper.vm
const coreEl = vm.$el.querySelector('.el-switch__core')
expect(coreEl.style.backgroundColor).toEqual('rgb(0, 255, 0)')
expect(vm.$el.style.getPropertyValue('--el-switch-on-color')).toEqual(
'#0f0'
)
expect(vm.$el.style.getPropertyValue('--el-switch-off-color')).toEqual(
'#f00'
)
expect(vm.$el.classList.contains('is-checked')).true
const coreWrapper = wrapper.find('.el-switch__core')
await coreWrapper.trigger('click')
expect(coreEl.style.backgroundColor).toEqual('rgb(255, 0, 0)')
expect(vm.$el.classList.contains('is-checked')).false
expect(vm.value).toEqual(false)
await coreWrapper.trigger('click')
expect(vm.$el.classList.contains('is-checked')).true
expect(vm.value).toEqual(true)
})

View File

@ -1,5 +1,5 @@
<template>
<div :class="switchKls" @click.prevent="switchValue">
<div :class="switchKls" :style="styles" @click.prevent="switchValue">
<input
:id="inputId"
ref="input"
@ -167,10 +167,6 @@ export default defineComponent({
watch(checked, () => {
input.value!.checked = checked.value
if (props.activeColor || props.inactiveColor) {
setBackgroundColor()
}
if (props.validateEvent) {
formItem?.validate?.('change').catch((err) => debugWarn(err))
}
@ -223,24 +219,19 @@ export default defineComponent({
}
}
const setBackgroundColor = (): void => {
const newColor = checked.value ? props.activeColor : props.inactiveColor
const coreEl = core.value
if (props.borderColor) coreEl!.style.borderColor = props.borderColor
else if (!props.borderColor) coreEl!.style.borderColor = newColor
coreEl!.style.backgroundColor = newColor
;(coreEl!.children[0] as HTMLDivElement).style.color = newColor
}
const styles = computed(() => {
return ns.cssVarBlock({
...(props.activeColor ? { 'on-color': props.activeColor } : null),
...(props.inactiveColor ? { 'off-color': props.inactiveColor } : null),
...(props.borderColor ? { 'border-color': props.borderColor } : null),
})
})
const focus = (): void => {
input.value?.focus?.()
}
onMounted(() => {
if (props.activeColor || props.inactiveColor || props.borderColor) {
setBackgroundColor()
}
input.value!.checked = checked.value
})
@ -256,6 +247,7 @@ export default defineComponent({
handleChange,
switchValue,
focus,
styles,
}
},
})

View File

@ -139,7 +139,11 @@ $switch-button-size: map.merge(
position: relative;
width: map.get($switch-core-width, 'default');
height: map.get($switch-core-height, 'default');
border: 1px solid getCssVar('switch-off-color');
border: 1px solid
var(
#{getCssVarName('switch-border-color')},
#{getCssVar('switch-off-color')}
);
outline: none;
border-radius: map.get($switch-core-border-radius, 'default');
box-sizing: border-box;
@ -208,7 +212,10 @@ $switch-button-size: map.merge(
@include when(checked) {
.#{$namespace}-switch__core {
border-color: getCssVar('switch-on-color');
border-color: var(
#{getCssVarName('switch-border-color')},
#{getCssVar('switch-on-color')}
);
background-color: getCssVar('switch-on-color');
.#{$namespace}-switch__action {