-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
357 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
--- | ||
title: Switch | Sharp-UI | ||
description: Switch 组件的文档 | ||
--- | ||
|
||
# Switch 开关 | ||
|
||
表示两种相互对立的状态间的切换,多用于触发「开/关」。 | ||
|
||
## 基础用法 | ||
|
||
绑定 v-model 到一个 Boolean 类型的变量。 可以使用 **--s-switch-on-color** 属性与 **--s-switch-off-color** 属性来设置开关的背景色。 | ||
|
||
<preview path="../demo/Switch/Basic.vue" title="基础Switch" description="Switch 基础用例"></preview> | ||
|
||
## 禁用状态 | ||
|
||
设置 **disabled** 属性,接受一个 boolean,设置true即可禁用。 | ||
|
||
<preview path="../demo/Switch/Disabled.vue" title="Switch 禁用状态" description="Switch 禁用状态"></preview> | ||
|
||
## 不同尺寸 | ||
|
||
设置 **size** 属性,接受**large / small**,呈现不同的尺寸。 | ||
|
||
<preview path="../demo/Switch/Size.vue" title="Switch 不同尺寸" description="Switch 不同尺寸"></preview> | ||
|
||
## 支持自定义 value 类型 | ||
|
||
你可以设置 **active-value** 和 **inactive-value** 属性, 它们接受 boolean | string | number 类型的值。 | ||
<preview path="../demo/Switch/CustomValue.vue" title="支持自定义 value 类型" description="Switch 支持自定义 value 类型"></preview> | ||
|
||
## 文字描述 | ||
|
||
使用 **active-text** 属性与 **inactive-text** 属性来设置开关的文字描述。 | ||
|
||
<preview path="../demo/Switch/Text.vue" title="支持文字描述" description="Switch 文字描述"></preview> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<script setup> | ||
import { ref } from 'vue' | ||
import Switch from '@/components/Switch/Switch.vue' | ||
const test = ref(true) | ||
</script> | ||
<template> | ||
<Switch v-model="test" /> | ||
</template> | ||
<style scoped> | ||
.s-switch { | ||
--s-switch-on-color:#13ce66; | ||
--s-switch-off-color:#ff4949 | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<script setup> | ||
import { ref } from 'vue' | ||
import Switch from '@/components/Switch/Switch.vue' | ||
const test = ref('right') | ||
</script> | ||
<template> | ||
<Switch v-model="test" activeValue="right" inactiveValue="wrong"/> | ||
<h4>model-value: {{test}}</h4> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<script setup> | ||
import { ref } from 'vue' | ||
import Switch from '@/components/Switch/Switch.vue' | ||
const test = ref(true) | ||
const test2 = ref(false) | ||
</script> | ||
<template> | ||
<div class="demo-switch-container"> | ||
<div class="demo-switch-container-title">正常:</div> | ||
<Switch v-model="test" /> <br/> | ||
</div> | ||
<div class="demo-switch-container"> | ||
<div class="demo-switch-container-title">禁用:</div> | ||
<Switch v-model="test2" disabled/> | ||
</div> | ||
</template> | ||
<style scoped> | ||
.demo-switch-container { | ||
display: flex; | ||
align-items: center; | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<script setup> | ||
import { ref } from 'vue' | ||
import Switch from '@/components/Switch/Switch.vue' | ||
const test = ref(false) | ||
</script> | ||
<template> | ||
<div class="switch-size-container"> | ||
<Switch v-model="test" size="large"/> | ||
<Switch v-model="test"/> | ||
<Switch v-model="test" size="small"/> | ||
</div> | ||
</template> | ||
<style scoped> | ||
.switch-size-container { | ||
display: flex; | ||
align-items: center; | ||
.s-switch { | ||
margin-right: 10px; | ||
} | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<script setup> | ||
import { ref } from 'vue' | ||
import Switch from '@/components/Switch/Switch.vue' | ||
const test = ref(false) | ||
</script> | ||
<template> | ||
<Switch v-model="test" activeText="ON" inactiveText="OFF"/> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
<template> | ||
<div | ||
class="s-switch" | ||
:class="{ | ||
[`s-switch--${size}`]: size, | ||
'is-disabled': disabled, | ||
'is-checked': checked | ||
}" | ||
@click="switchValue" | ||
> | ||
<input | ||
class="s-switch__input" | ||
type="checkbox" | ||
role="switch" | ||
ref="input" | ||
:name="name" | ||
:disabled="disabled" | ||
@keydown.enter="switchValue" | ||
/> | ||
<div class="s-switch__core"> | ||
<div class="s-switch__core-inner"> | ||
<span v-if="activeText || inactiveText" class="s-switch__core-inner-text"> | ||
{{ checked ? activeText : inactiveText }} | ||
</span> | ||
</div> | ||
<div class="s-switch__core-action"></div> | ||
</div> | ||
</div> | ||
</template> | ||
|
||
<script setup lang="ts"> | ||
import { computed, onMounted, ref, watch } from 'vue' | ||
import type { SwitchProps, SwitchEmits } from './types' | ||
defineOptions({ name: 's-switch', inheritAttrs: false }) | ||
// 定义组件接收的 props | ||
const props = withDefaults(defineProps<SwitchProps>(), { | ||
activeValue: true, // 开启状态的值 | ||
inactiveValue: false // 关闭状态的值 | ||
}) | ||
// 定义组件发出的事件 | ||
const emits = defineEmits<SwitchEmits>() | ||
// 创建一个 input 元素的引用 | ||
const input = ref<HTMLInputElement>() | ||
// 使用 ref 来跟踪开关的内部值 | ||
const innerValue = ref(props.modelValue) | ||
// 计算当前是否被选中 | ||
const checked = computed(() => innerValue.value === props.activeValue) | ||
// 切换开关状态的逻辑 | ||
const switchValue = () => { | ||
if (props.disabled) return // 如果设置了 disabled,则不进行任何操作 | ||
const newValue = checked.value ? props.inactiveValue : props.activeValue | ||
innerValue.value = newValue | ||
emits('update:modelValue', newValue) // 更新父组件绑定的值 | ||
emits('change', newValue) // 发出 change 事件 | ||
} | ||
// 在组件挂载时,设置 input 元素的 checked 状态 | ||
onMounted(() => { | ||
input.value!.checked = checked.value | ||
}) | ||
// 监听 checked 的变化,更新 input 元素的 checked 状态 | ||
watch(checked, (val) => { | ||
input.value!.checked = val | ||
}) | ||
// 监听 props.modelValue 的变化,更新 innerValue 的值 | ||
watch( | ||
() => props.modelValue, | ||
(newValue) => { | ||
innerValue.value = newValue | ||
} | ||
) | ||
</script> | ||
|
||
<style scoped></style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
.s-switch { | ||
--s-switch-on-color: var(--s-color-primary); | ||
--s-switch-off-color: var(--s-border-color); | ||
--s-switch-on-border-color: var(--s-color-primary); | ||
--s-switch-off-border-color: var(--s-border-color); | ||
} | ||
|
||
.s-switch { | ||
display: inline-flex; | ||
align-items: center; | ||
font-size: 14px; | ||
line-height: 20px; | ||
height: 32px; | ||
.s-switch__input { | ||
position: absolute; | ||
width: 0; | ||
height: 0; | ||
opacity: 0; | ||
margin: 0; | ||
&:focus-visible { | ||
& ~ .s-switch__core { | ||
outline: 2px solid var(--s-switch-on-color); | ||
outline-offset: 1px; | ||
} | ||
} | ||
} | ||
&.is-disabled { | ||
opacity: .6; | ||
.s-switch__core { | ||
cursor: not-allowed; | ||
} | ||
} | ||
&.is-checked { | ||
.s-switch__core { | ||
border-color:var(--s-switch-on-border-color); | ||
background-color: var(--s-switch-on-color); | ||
.s-switch__core-action { | ||
left: calc(100% - 17px); | ||
} | ||
.s-switch__core-inner { | ||
padding: 0 18px 0 4px; | ||
} | ||
} | ||
} | ||
} | ||
.s-switch--large { | ||
font-size: 14px; | ||
line-height: 24px; | ||
height: 40px; | ||
.s-switch__core { | ||
min-width: 50px; | ||
height: 24px; | ||
border-radius: 12px; | ||
.s-switch__core-action { | ||
width: 20px; | ||
height: 20px; | ||
} | ||
} | ||
&.is-checked { | ||
.s-switch__core .s-switch__core-action { | ||
left: calc(100% - 21px); | ||
color: var(--s-switch-on-color); | ||
} | ||
} | ||
} | ||
.s-switch--small { | ||
font-size: 12px; | ||
line-height: 16px; | ||
height: 24px; | ||
.s-switch__core { | ||
min-width: 30px; | ||
height: 16px; | ||
border-radius: 8px; | ||
.s-switch__core-action { | ||
width: 12px; | ||
height: 12px; | ||
} | ||
} | ||
&.is-checked { | ||
.s-switch__core .s-switch-core-action { | ||
left: calc(100% - 13px); | ||
color: var(--s-switch-on-color); | ||
} | ||
} | ||
} | ||
.s-switch__core { | ||
display: inline-flex; | ||
align-items: center; | ||
position: relative; | ||
height: 20px; | ||
min-width: 40px; | ||
border: 1px solid var(--s-switch-off-border-color); | ||
outline: none; | ||
border-radius: 10px; | ||
box-sizing: border-box; | ||
background: var(--s-switch-off-color); | ||
cursor: pointer; | ||
transition: border-color var(--s-transition-duration),background-color var(--s-transition-duration); | ||
.s-switch__core-action { | ||
position: absolute; | ||
left: 1px; | ||
border-radius: var(--s-border-radius-circle); | ||
width: 16px; | ||
height: 16px; | ||
background-color: var(--s-color-white); | ||
transition: all var(--s-transition-duration); | ||
} | ||
.s-switch__core-inner { | ||
width: 100%; | ||
transition: all var(--s-transition-duration); | ||
height: 16px; | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
overflow: hidden; | ||
padding: 0 4px 0 18px; | ||
.s-switch__core-inner-text { | ||
font-size: 12px; | ||
color: var(--s-color-white); | ||
user-select: none; | ||
overflow: hidden; | ||
text-overflow: ellipsis; | ||
white-space: nowrap; | ||
} | ||
} | ||
} |
Oops, something went wrong.