forked from opentiny/tiny-vue
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:
parent
06c39be857
commit
59bc73b23d
|
@ -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: ''
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -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>
|
|
@ -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()
|
||||
})
|
|
@ -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>
|
|
@ -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: {
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>)
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue