Files
xh-medical-sign-web/clinical-web/src/components/ToggleSwitch.vue
T
yelan 3628c5ed86 feat(users): 员工表单对齐原型并优化密码策略与错误文案
- 新增胶囊开关组件,账号状态与强制改密改用开关
- 角色由多选改为互斥单选,编辑态多角色给出收敛提示
- 密码策略增加特殊字符要求,规则提示改为短标签横排
- 移除邮箱字段及相关脱敏、清除逻辑
- 接口错误经 toUserMessage 中文化,透传后端校验原因
2026-09-30 10:33:24 +08:00

83 lines
1.5 KiB
Vue

<script setup lang="ts">
/**
* 胶囊开关(对齐原型 `.switch`:36×20 胶囊 + 圆形滑块,开启为 --ok)。
* 用 button + role="switch" 而不是 checkbox,避免各浏览器对 checkbox 的默认外观差异。
*/
const props = defineProps<{
modelValue: boolean
disabled?: boolean
/** 供读屏使用的名称;视觉标签由调用方提供 */
label?: string
}>()
const emit = defineEmits<{
'update:modelValue': [value: boolean]
}>()
function toggle() {
if (props.disabled) {
return
}
emit('update:modelValue', !props.modelValue)
}
</script>
<template>
<button
type="button"
class="switch"
:class="{ 'is-on': modelValue }"
role="switch"
:aria-checked="modelValue"
:aria-label="label"
:disabled="disabled"
@click="toggle"
>
<span class="switch__thumb" />
</button>
</template>
<style scoped>
.switch {
position: relative;
flex-shrink: 0;
width: 36px;
height: 20px;
padding: 0;
background: #cbd8de;
border: none;
border-radius: 20px;
transition: background 0.2s;
cursor: pointer;
}
.switch.is-on {
background: var(--ok);
}
.switch:disabled {
cursor: not-allowed;
opacity: 0.5;
}
.switch:focus-visible {
outline: 2px solid var(--brand);
outline-offset: 2px;
}
.switch__thumb {
position: absolute;
top: 2px;
left: 2px;
width: 16px;
height: 16px;
background: #fff;
border-radius: 50%;
transition: left 0.2s;
}
.switch.is-on .switch__thumb {
left: 18px;
}
</style>