Demos
How to import
<script setup lang="ts">
import { Switch } from '@fibrous/semi-ui-vue';
</script>
Basic Usage
You can monitor state changes through @change, and set the selected state through defaultChecked or modelValue (v-model).
Use aria-label to describe the specific function of the Switch
Code
<script setup lang="ts">
import { Switch } from '@fibrous/semi-ui-vue';
const log = (checked: boolean) => console.log(checked);
</script>
<template>
<div>
<Switch aria-label="a switch for demo" @change="log" />
<br />
<Switch aria-label="a switch for semi demo" defaultChecked @change="log" />
</div>
</template>Size
Code
<script setup lang="ts">
import { Space, Switch } from '@fibrous/semi-ui-vue';
</script>
<template>
<div>
<Space :style="{ marginBottom: '10px', display: 'block' }">
<Switch aria-label="a switch for demo" size="small" />
<Switch aria-label="a switch for demo" defaultChecked size="small" />
<Switch aria-label="a switch for demo" loading size="small" />
<Switch aria-label="a switch for demo" defaultChecked loading size="small" />
</Space>
<Space :style="{ marginBottom: '10px', display: 'block' }">
<Switch aria-label="a switch for demo" />
<Switch aria-label="a switch for demo" defaultChecked />
<Switch aria-label="a switch for demo" loading />
<Switch aria-label="a switch for demo" defaultChecked loading />
</Space>
<Space>
<Switch aria-label="a switch for demo" size="large" />
<Switch aria-label="a switch for demo" defaultChecked size="large" />
<Switch aria-label="a switch for demo" loading size="large" />
<Switch aria-label="a switch for demo" defaultChecked loading size="large" />
</Space>
</div>
</template>Disabled
Code
<script setup lang="ts">
import { Switch } from '@fibrous/semi-ui-vue';
</script>
<template>
<div>
<Switch aria-label="a switch for demo" disabled />
<br />
<Switch aria-label="a switch for demo" disabled modelValue />
</div>
</template>With text
Can pass the #checkedText and #uncheckedText slots to set the text of the switch
The long text is recommended to be placed directly on the outside.
Note: This does not work with the smallest switch (size = 'small')
Code
<script setup lang="ts">
import { Switch } from '@fibrous/semi-ui-vue';
</script>
<template>
<div>
<Switch aria-label="带开关文字的开关">
<template #checkedText>开</template>
<template #uncheckedText>关</template>
</Switch>
<Switch aria-label="带符号文字的开关" :style="{ marginLeft: '5px' }">
<template #checkedText>|</template>
<template #uncheckedText>〇</template>
</Switch>
<br />
<br />
<Switch aria-label="带开关文字的开关,已开启" defaultChecked>
<template #checkedText>开</template>
<template #uncheckedText>关</template>
</Switch>
<Switch aria-label="带符号文字的开关,已开启" defaultChecked :style="{ marginLeft: '5px' }">
<template #checkedText>|</template>
<template #uncheckedText>〇</template>
</Switch>
<br />
<br />
<Switch aria-label="大号带开关文字的开关" size="large">
<template #checkedText>开</template>
<template #uncheckedText>关</template>
</Switch>
<Switch aria-label="大号带符号文字的开关" size="large" :style="{ marginLeft: '5px' }">
<template #checkedText>|</template>
<template #uncheckedText>〇</template>
</Switch>
<br />
<br />
<Switch aria-label="大号带开关文字的开关,已开启" defaultChecked size="large">
<template #checkedText>开</template>
<template #uncheckedText>关</template>
</Switch>
<Switch aria-label="大号带符号文字的开关,已开启" defaultChecked size="large" :style="{ marginLeft: '5px' }">
<template #checkedText>|</template>
<template #uncheckedText>〇</template>
</Switch>
</div>
</template>Compared to setting the embedded text through checkedText and uncheckedText, we recommend placing the text description outside the Switch
已关闭
Code
<script setup lang="ts">
import { ref } from 'vue';
import { Switch, Typography } from '@fibrous/semi-ui-vue';
const { Title } = Typography;
const open = ref<boolean>();
</script>
<template>
<div :style="{ display: 'flex', alignItems: 'center' }">
<Title :heading="6" :style="{ margin: '8px' }">{{ open ? '已开启' : '已关闭' }}</Title>
<Switch v-model="open" aria-label="a switch for demo" />
</div>
</template>Controlled component
Whether the component is selected depends entirely on the incoming modelValue, used with v-model. With a one-way :modelValue and no write-back, a click only notifies and the passed value decides what is shown.
Code
<script setup lang="ts">
import { ref } from 'vue';
import { Switch } from '@fibrous/semi-ui-vue';
const checked = ref(true);
</script>
<template>
<Switch v-model="checked" aria-label="a switch for demo" />
</template>loading
You can turn on the loading state by setting loading="true".
Code
<script setup lang="ts">
import { Switch } from '@fibrous/semi-ui-vue';
</script>
<template>
<div>
<Switch aria-label="Loading switch" loading />
<br />
<Switch aria-label="Loading switch, on" defaultChecked loading />
</div>
</template>API reference
Props
| Property | Description | Type | Default |
|---|---|---|---|
| modelValue | Whether the switch is on, used with v-model. When given, this value decides; without a write-back, a click only notifies. | boolean | undefined |
| defaultChecked | Initial state when uncontrolled. | boolean | semiGlobalDefault("Switch", "defaultChecked") |
| disabled | Whether the switch is disabled. | boolean | semiDefault("Switch", "disabled", false) |
| loading | Whether the switch is loading. While loading, the input stays focusable with aria-disabled, and toggles are ignored without emitting events. | boolean | semiDefault("Switch", "loading", false) |
| size | Switch size: large, default or small. | Size | semiDefault("Switch", "size", "default") |
Events
| Event | Description | Callback parameters |
|---|---|---|
| update:modelValue | Emitted when the user toggles the switch, for v-model to write back. | [checked: boolean] |
| change | Emitted when the user toggles the switch, with the new state and the native event. | [checked: boolean, event: Event] |
Slots
| Slot | Description | Scope parameters |
|---|---|---|
| checkedText | Content shown when on. Not shown when size is small. | any |
| uncheckedText | Content shown when off. Not shown when size is small. | any |
Exposes
| Name | Description | Type |
|---|---|---|
| None |
class and style land on the root element. id, name, tabindex, autofocus, aria-* and focus and blur listeners passed as attrs land on the inner native input; other native attributes and listeners (such as @mouseenter) land on the root element.
Accessibility
ARIA
- The inner input of Switch has a
switchrole, and its on or off state is expressed by the native checked state of the input. - As a form field, it should have a Label.
- It is recommended to use
aria-labelto describe the current label function, oraria-labelledbyto point to a visible label on the page.
Keyboard and Focus
- Keyboard users can use
TabandShift + Tabto switch focus. - When focusing, you can switch on or off by pressing the
Spacekey.
Content Guidelines
- Switch description
- First letter is capitalized, no punctuation is required
- Indirectly and explicitly state whether the setting is on or off
- If needed, explain to the user what the on and off states represent
Design Tokens
| Sass variable | Value | Usage |
|---|---|---|
| $transition_duration-switch-bg | 200ms | 开关-背景色-动画持续时间 |
| $transition_function-switch-bg | var(--semi-transition_function-easeIn) | 开关-背景色-过渡曲线 |
| $transition_delay-switch-bg | var(--semi-transition_delay-none) | 开关-背景色-延迟时间 |
| $spacing-switch_unchecked-translateX | 2px | 未选中态开关滑块位移距离 |
| $spacing-switch_spin_unchecked-translateX | 2px | 未选中态加载图标位移距离 |
| $spacing-switch_checked-translateX | 18px | 选中态开关滑块位移距离 |
| $spacing-switch_spin_checked-translateX | 16px | 选中态加载图标位移距离 |
| $spacing-switch_expand_large-translateX | 10px | |
| $spacing-switch_unchecked_large-translateX | 3px | 大尺寸未选中态开关滑块位移距离 |
| $spacing-switch_spin_unchecked_large-translateX | 2px | 大尺寸未选中态加载图标位移距离 |
| $spacing-switch_checked_large-translateX | 26px | 大尺寸选中态开关滑块位移距离 |
| $spacing-switch_spin_checked_large-translateX | 22px | 大尺寸选中态加载图标位移距离 |
| $spacing-switch_expand_small-translateX | 2px | |
| $spacing-switch_unchecked_small-translateX | 1px | 小尺寸未选中态开关滑块位移距离 |
| $spacing-switch_spin_unchecked_small-translateX | 2px | 小尺寸未选中态加载图标位移距离 |
| $spacing-switch_checked_small-translateX | 11px | 小尺寸选中态开关滑块位移距离 |
| $spacing-switch_spin_checked_small-translateX | 10px | 小尺寸选中态加载图标位移距离 |
| $motion-switch-transitionDuration | 200ms | 开关动画时长 |
| $color-switch_default-bg-default | var(--semi-color-fill-0) | 关闭态(未选中)开关背景色 - 默认 |
| $color-switch_default-bg-hover | var(--semi-color-fill-1) | 关闭态开关背景色 - 悬浮 |
| $color-switch_default-bg-active | var(--semi-color-fill-2) | 关闭态开关背景色 - 按下 |
| $color-switch_default-border-default | transparent | 关闭态开关描边颜色 |
| $color-switch_checked-bg-default | var(--semi-color-success) | 开启态开关背景色 - 默认 |
| $color-switch_checked-bg-hover | var(--semi-color-success-hover) | 开启态开关背景色 - 悬浮 |
| $color-switch_checked-bg-active | var(--semi-color-success-active) | 开启态开关背景色 - 按下 |
| $color-switch_disabled-bg-default | transparent | 禁用态开关背景色 |
| $color-switch_disabled-bg-hover | transparent | 禁用态开关背景色 - 悬浮 |
| $color-switch_disabled-bg-active | transparent | 禁用态开关背景色 - 按下 |
| $color-switch_disabled-border-default | var(--semi-color-border) | 禁用态开关描边颜色 |
| $color-switch_disabled-bg-hover | transparent | 禁用态开关背景色 - 悬浮 |
| $color-switch_checked_disabled-bg-default | var(--semi-color-success-disabled) | 禁用开启态开关背景颜色 |
| $color-switch_checked_disabled-border-default | transparent | 禁用开启态开关描边颜色 |
| $color-switch_knob-bg-default | var(--semi-white) | 开关滑块背景颜色 - 关闭态 |
| $color-switch_knob-bg-checked | var(--semi-white) | 开关滑块背景颜色 - 开启态 |
| $color-switch_knob-border-default | var(--semi-color-border) | 开关滑块描边颜色 |
| $color-switch_checked-text-default | var(--semi-color-white) | 开启态开关文案颜色 |
| $color-switch_unchecked-text-default | var(--semi-color-text-2) | 关闭态开关文案颜色 |
| $color-switch_loading_spin-default | var(--semi-color-white) | 加载态开关loading图标颜色 |
| $color-switch_spin_checked-bg-default | var(--semi-color-success-hover) | 已开启开关加载态loading背景颜色 |
| $color-switch_spin_unchecked-bg-default | var(--semi-color-fill-1) | 已关闭开关加载态loading背景颜色 |
| $color-switch_primary-outline-focus | $color-focus-ring | 开关轮廓 - 聚焦 |
| $width-switch | 40px | 开关宽度 |
| $height-switch | 24px | 开关高度 |
| $width-switch_knob_expand | 6px | 开关滑块按压时延展宽度 |
| $width-switch_knob_default | 18px | 开关滑块宽度 |
| $width-switch_knob_active | $width-switch_knob_default + $width-switch_knob_expand | 开关滑块按下态宽度 |
| $height-switch_large | 32px | 大尺寸开关高度 |
| $width-switch_large | 54px | 大尺寸开关宽度 |
| $width-switch_knob_large | 24px | 大尺寸开关滑块宽度 |
| $width-switch_knob_large_active | $width-switch_knob_large + $spacing-switch_expand_large-translateX | 大尺寸开关滑块按下态宽度 |
| $height-switch_small | 16px | 小尺寸开关高度 |
| $width-switch_small | 26px | 小尺寸开关宽度 |
| $width-switch_knob_large_small | 12px | 小尺寸开关滑块宽度 |
| $width-switch_knob_small_active | $width-switch_knob_large_small + $spacing-switch_expand_small-translateX | 小尺寸开关滑块按下态宽度 |
| $width-switch_knob_disabled-border | 1px | 禁用态开关滑块边框宽度 |
| $width-switch_checked_unchecked_text | 26px | 开关文案宽度 |
| $width-switch_spin-small | 10px | 小尺寸开关加载 spin 宽度 |
| $width-switch_spin-default | 18px | 默认尺寸开关加载 spin 宽度 |
| $width-switch_spin-large | 28px | 大尺寸开关加载 spin 宽度 |
| $width-switch-outline | $width-focus-ring | 开关轮廓宽度 |
| $spacing-switch_knob-padding | 2px | 开关滑块顶部边距 |
| $spacing-switch_knob_large-padding | 3px | 大尺寸开关滑块顶部边距 |
| $spacing-switch_knob_small-padding | 1px | 小尺寸开关滑块顶部边距 |
| $spacing-switch_knob-left | 0px | 开关滑块左侧偏移距离 |
| $radius-switch | $height-switch * 0.5 | 开关圆角 |
| $radius-switch_large | $height-switch_large * 0.5 | 大尺寸开关圆角 |
| $radius-switch_small | $height-switch_small * 0.5 | 小尺寸开关圆角 |