Skip to content

Commit 4c1dcae

Browse files
authored
feat(switch): add width property to support custom switch width (#3879)
1 parent 388f1c2 commit 4c1dcae

File tree

8 files changed

+133
-3
lines changed

8 files changed

+133
-3
lines changed

examples/sites/demos/apis/switch.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,21 @@ export default {
111111
pcDemo: 'custom-true-false-value',
112112
mfDemo: ''
113113
},
114+
{
115+
name: 'width',
116+
type: 'number | string',
117+
defaultValue: '',
118+
desc: {
119+
'zh-CN': '定义开关的宽度',
120+
'en-US': 'Define the width of the switch'
121+
},
122+
mode: ['pc'],
123+
mfDemo: '',
124+
pcDemo: 'width',
125+
meta: {
126+
stable: '3.28.0'
127+
}
128+
},
114129
{
115130
name: 'types',
116131
type: 'string',

examples/sites/demos/pc/app/switch/webdoc/switch.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,18 @@ export default {
2828
},
2929
codeFiles: ['mini-mode.vue']
3030
},
31+
{
32+
demoId: 'width',
33+
name: {
34+
'zh-CN': '自定义宽度',
35+
'en-US': 'Custom width'
36+
},
37+
desc: {
38+
'zh-CN': '<p>通过 <code>width</code> 设置开关的宽度。</p>',
39+
'en-US': '<p>Set the width of the switch through <code>width</code> .</p>'
40+
},
41+
codeFiles: ['width.vue']
42+
},
3143
{
3244
demoId: 'loading',
3345
name: {
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<template>
2+
<div class="switch-demo">
3+
<div class="demo-item">
4+
<div class="demo-title">number类型</div>
5+
<tiny-switch :width="150"></tiny-switch>
6+
</div>
7+
8+
<div class="demo-item">
9+
<div class="demo-title">string类型</div>
10+
<tiny-switch width="150PX"></tiny-switch>
11+
</div>
12+
</div>
13+
</template>
14+
15+
<script setup>
16+
import { TinySwitch } from '@opentiny/vue'
17+
</script>
18+
19+
<style scoped>
20+
.demo-item {
21+
padding: 15px;
22+
}
23+
24+
.demo-title {
25+
font-size: 14px;
26+
font-weight: 500;
27+
margin-bottom: 10px;
28+
}
29+
</style>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { test, expect } from '@playwright/test'
2+
3+
test('width 属性', async ({ page }) => {
4+
page.on('pageerror', (exception) => expect(exception).toBeNull())
5+
await page.goto('switch#width')
6+
7+
const demo = page.locator('#width')
8+
const switchBtns = demo.locator('.tiny-switch')
9+
10+
// 测试 number 类型的 width
11+
const numberSwitch = switchBtns.nth(0)
12+
await expect(numberSwitch).toHaveCSS('width', '150px')
13+
14+
// 测试 string 类型的 width
15+
const stringSwitch = switchBtns.nth(1)
16+
await expect(stringSwitch).toHaveCSS('width', '150px')
17+
})
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<template>
2+
<div class="switch-demo">
3+
<div class="demo-item">
4+
<div class="demo-title">number类型</div>
5+
<tiny-switch :width="150"></tiny-switch>
6+
</div>
7+
8+
<div class="demo-item">
9+
<div class="demo-title">string类型</div>
10+
<tiny-switch width="150PX"></tiny-switch>
11+
</div>
12+
</div>
13+
</template>
14+
15+
<script>
16+
import { TinySwitch } from '@opentiny/vue'
17+
18+
export default {
19+
components: {
20+
TinySwitch
21+
}
22+
}
23+
</script>
24+
25+
<style scoped>
26+
.demo-item {
27+
padding: 15px;
28+
}
29+
30+
.demo-title {
31+
font-size: 14px;
32+
font-weight: 500;
33+
margin-bottom: 10px;
34+
}
35+
</style>

packages/renderless/src/switch/vue.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,25 @@ export const renderless = (
4545
} else {
4646
return props.showText
4747
}
48+
}),
49+
// 添加 switchStyle 计算属性
50+
switchStyle: computed(() => {
51+
if (props.width) {
52+
return {
53+
width: typeof props.width === 'number' ? `${props.width}px` : props.width
54+
}
55+
}
56+
return {}
57+
}),
58+
// 添加 displayOnlyStyle 计算属性
59+
displayOnlyStyle: computed(() => {
60+
if (props.width) {
61+
return {
62+
width: typeof props.width === 'number' ? `${props.width}px` : props.width,
63+
display: 'inline-block'
64+
}
65+
}
66+
return {}
4867
})
4968
})
5069

packages/vue/src/switch/src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ export const switchProps = {
6969
loading: {
7070
type: Boolean,
7171
default: false
72-
}
72+
},
73+
width: [Number, String]
7374
}
7475

7576
export default defineComponent({

packages/vue/src/switch/src/pc.vue

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
v-if="!state.isDisplayOnly"
1515
:class="[state.wrapClasses, state.showText ? 'tiny-switch__text' : '']"
1616
:tabindex="tabindex"
17+
:style="state.switchStyle"
1718
@click="toggle"
1819
@keydown.space="toggle"
1920
@keydown.enter="toggle"
@@ -36,7 +37,7 @@
3637
<slot v-if="state.currentValue === falseValue && !loading" name="inactive-icon"></slot>
3738
</span>
3839
</span>
39-
<span v-else>
40+
<span v-else :style="state.displayOnlyStyle">
4041
<slot v-if="state.currentValue === trueValue" name="open">{{ t('yes') }}</slot>
4142
<slot v-if="state.currentValue === falseValue" name="close">{{ t('no') }}</slot></span
4243
>
@@ -62,7 +63,8 @@ export default defineComponent({
6263
'showText',
6364
'beforeChange',
6465
'displayOnly',
65-
'loading'
66+
'loading',
67+
'width'
6668
],
6769
components: { IconLoading: IconLoadingShadow() },
6870
setup(props, context) {

0 commit comments

Comments
 (0)