feat(Switch): [switch] suppor custom open and close icon. (#1551)

* feat(Swtich): [Switch] suppor custom icon

* test(Switch): [Switch] add the the custom icon feature's unit test

* test(Swtich): [Switch] improve e2e test of costom icon

* test(Switch): [Switch]Update custom-open-close-icon.spec.ts

* test(switch): fix swtich custom-open-close-icon e2e test
This commit is contained in:
AcWrong02 2024-07-26 16:50:16 +08:00 committed by GitHub
parent 06c39be857
commit 59bc73b23d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 121 additions and 5 deletions

View File

@ -175,6 +175,30 @@ export default {
mode: ['pc', 'mobile-first'],
pcDemo: 'custom-open-close',
mfDemo: ''
},
{
name: 'active-icon',
type: '',
defaultValue: '',
desc: {
'zh-CN': '开启时开关的图标',
'en-US': 'Icon of the switch when turned on'
},
mode: ['pc'],
pcDemo: 'custom-open-close-icon',
mfDemo: ''
},
{
name: 'inactive-icon',
type: '',
defaultValue: '',
desc: {
'zh-CN': '关闭时开关的图标',
'en-US': 'Icon of the switch when turned off'
},
mode: ['pc'],
pcDemo: 'custom-open-close-icon',
mfDemo: ''
}
]
}

View File

@ -0,0 +1,20 @@
<template>
<tiny-switch>
<template #active-icon>
<TinyIconArrowLeft />
</template>
<template #inactive-icon>
<TinyIconArrowRight />
</template>
</tiny-switch>
</template>
<script setup>
import { Switch } from '@opentiny/vue'
import { IconArrowLeft, IconArrowRight } from '@opentiny/vue-icon'
const TinyIconArrowLeft = IconArrowLeft()
const TinyIconArrowRight = IconArrowRight()
const TinySwitch = Switch
</script>

View File

@ -0,0 +1,15 @@
import { test, expect } from '@playwright/test'
test('自定义开关图标', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('switch#custom-open-close-icon')
const demo = page.locator('#custom-open-close-icon')
const switchContainer = demo.locator('.tiny-switch')
const switchBtn = switchContainer.locator('.tiny-switch__button').first()
const switchIcon = switchBtn.locator('.tiny-svg').first()
await expect(switchIcon).not.toBeNull()
})

View File

@ -0,0 +1,23 @@
<template>
<tiny-switch>
<template #active-icon>
<TinyIconArrowLeft />
</template>
<template #inactive-icon>
<TinyIconArrowRight />
</template>
</tiny-switch>
</template>
<script>
import { Switch } from '@opentiny/vue'
import { IconArrowLeft, IconArrowRight } from '@opentiny/vue-icon'
export default {
components: {
TinySwitch: Switch,
TinyIconArrowLeft: IconArrowLeft(),
TinyIconArrowRight: IconArrowRight()
}
}
</script>

View File

@ -79,6 +79,19 @@ export default {
},
codeFiles: ['dynamic-disable.vue']
},
{
demoId: 'custom-open-close-icon',
name: {
'zh-CN': '自定义开关图标',
'en-US': 'Custom switch icon'
},
desc: {
'zh-CN': '<p>通过具名插槽 <code>active-icon</code> 和 <code>inactive-icon</code> 自定义开关图标。</p>',
'en-US':
'<p>Customize switch icons through named slots<code>active icon</code>and<code>inactive icon</code> .</p>'
},
codeFiles: ['custom-open-close-icon.vue']
},
{
demoId: 'event-change',
name: {

View File

@ -79,7 +79,10 @@
border-color: var(--ti-switch-checked-disabled-border-color);
}
&::after {
&__button {
display: flex;
justify-content: center;
align-items: center;
content: '';
width: var(--ti-switch-dot-size);
height: var(--ti-switch-dot-size);
@ -104,9 +107,9 @@
text-align: center;
overflow: hidden;
}
}
&:after {
&&-checked .@{switch-prefix-cls}__button {
left: calc(100% - var(--ti-switch-dot-offset));
}
}
}

View File

@ -1,9 +1,12 @@
import { mountPcMode } from '@opentiny-internal/vue-test-utils'
import { describe, expect, test, vi } from 'vitest'
import Switch from '@opentiny/vue-switch'
import { IconArrowLeft, IconArrowRight } from '@opentiny/vue-icon'
import { nextTick, ref } from 'vue'
let value = false
const TinyIconArrowLeft = IconArrowLeft()
const TinyIconArrowRight = IconArrowRight()
describe('PC Mode', () => {
const mount = mountPcMode
@ -13,7 +16,7 @@ describe('PC Mode', () => {
expect(wrapper.find('.mini').exists()).toBe(true)
})
test('slot', async () => {
test('open & close slot', async () => {
const wrapper = mount(() => (
<Switch
v-model={value}
@ -26,6 +29,17 @@ describe('PC Mode', () => {
expect(wrapper.find('.no').exists()).toBe(true)
})
test('active-icon & inactive-icon slot', async () => {
const wrapper = mount(Switch, {
modelValue: value,
slots: {
'active-icon': () => <TinyIconArrowLeft />,
'inactive-icon': () => <TinyIconArrowRight />
}
})
expect(wrapper.find('.tiny-svg').exists()).toBe(true)
})
test('events', async () => {
const handleClick = vi.fn()
const wrapper = mount(() => <Switch v-model={value} onChange={handleClick}></Switch>)

View File

@ -24,6 +24,10 @@
<slot v-if="state.currentValue === falseValue" name="close">OFF</slot>
</div>
</span>
<span class="tiny-switch__button">
<slot v-if="state.currentValue === trueValue" name="active-icon"></slot>
<slot v-if="state.currentValue === falseValue" name="inactive-icon"></slot>
</span>
</span>
<span v-else>
<slot v-if="state.currentValue === trueValue" name="open">{{ t('yes') }}</slot>