refactor(switch): add rail-style prop

This commit is contained in:
07akioni 2021-12-03 02:48:30 +08:00
parent a85782db14
commit 5f8ede0595
7 changed files with 69 additions and 63 deletions

View File

@ -6,7 +6,7 @@
### Feats
- `n-switch` add `activeColor` & `inactiveColor` & `activeButtonColor` & `inactiveButtonColor` prop, closes [#1718](https://github.com/TuSimple/naive-ui/issues/1718)
- `n-switch` add `rail-style` prop, closes [#1718](https://github.com/TuSimple/naive-ui/issues/1718)
- `n-image` add `can-preview` & `on-load` prop, closes [#1647](https://github.com/TuSimple/naive-ui/issues/1647).
- `n-image` add `loading` & `errorbox` slot.
- `n-data-table` add `on-update:expanded-row-keys` prop.

View File

@ -6,7 +6,7 @@
### Feats
- `n-switch` 新增 `activeColor` & `inactiveColor` & `activeButtonColor` & `inactiveButtonColor` 属性,关闭 [#1718](https://github.com/TuSimple/naive-ui/issues/1718)
- `n-switch` 新增 `rail-style` 属性,关闭 [#1718](https://github.com/TuSimple/naive-ui/issues/1718)
- `n-image` 新增 `can-preview` & `on-load` 属性,关闭 [#1647](https://github.com/TuSimple/naive-ui/issues/1647)
- `n-image` 新增 `loading` & `errorbox` slot
- `n-data-table` 新增 `on-update:expanded-row-keys` 属性

View File

@ -1,25 +1,33 @@
# Custom colors
The colours of the rainbow.
# Customizing colors
```html
<n-space>
<n-switch
v-model:value="active"
size="large"
activeColor="linear-gradient( to right, orangered, orange, gold, lightgreen, cyan, dodgerblue, mediumpurple, hotpink, orangered)"
activeButtonColor="rgba(255,255,255,0.5)"
/>
</n-space>
<n-switch :rail-style="railStyle">
<template #checked>Checked</template>
<template #unchecked>Unchecked</template>
</n-switch>
```
```js
import { defineComponent, ref } from 'vue'
import { defineComponent } from 'vue'
export default defineComponent({
setup () {
return {
active: ref(true)
railStyle: ({ focused, checked }) => {
const style = {}
if (checked) {
style.background = '#d03050'
if (focused) {
style.boxShadow = '0 0 0 2px #d0305040'
}
} else {
style.background = '#2080f0'
if (focused) {
style.boxShadow = '0 0 0 2px #2080f040'
}
}
return style
}
}
}
})

View File

@ -21,19 +21,18 @@ color
| Name | Type | Default | Description |
| --- | --- | --- | --- |
| checked-style | `string` | `undefined` | Style of the checked state. |
| checked-value | `string \| boolean \| number` | `true` | Value of checked state. |
| default-value | `boolean` | `false` | Default value. |
| disabled | `boolean` | `false` | Whether to disable the switch. |
| loading | `boolean` | `false` | Whether to show loading state. |
| rail-style | `(info: { focused: boolean, checked: boolean }) => (CSSProperties \| string)` | `undefined` | Rail style generator. |
| round | `boolean` | `true` | Whether the switch has rounded corners.   |
| size | `'small' \| 'medium' \| 'large'` | `'medium'` | The size of the switch. |
| value | `boolean` | `undefined` | Value when being set manually. |
| unchecked-value | `string \| boolean \| number` | `false` | Value of unchecked state. |
| unchecked-color | `string` | `undefined` | Background of unchecked state. |
| unchecked-style | `string \| boolean \| number` | `false` | Style of the unchecked state. |
| on-update:value | `(value: boolean) => void` | `undefined` | Callback when the component's value changes. |
| activeColor | `string` | `undefined` | Background of checked state. |
| inactiveColor | `string` | `undefined` | Background of unchecked state. |
| activeButtonColor | `string` | `undefined` | Button background of checked state. |
| inactiveButtonColor | `string` | `undefined` | Button background of unchecked state. |
### Switch Slots

View File

@ -1,25 +1,33 @@
# 自定义颜色
生活,就应该五彩斑斓
```html
<n-space>
<n-switch
v-model:value="active"
size="large"
activeColor="linear-gradient( to right, orangered, orange, gold, lightgreen, cyan, dodgerblue, mediumpurple, hotpink, orangered)"
activeButtonColor="rgba(255,255,255,0.5)"
/>
</n-space>
<n-switch :rail-style="railStyle">
<template #checked>傍晚六点下班</template>
<template #unchecked>午夜零点下班</template>
</n-switch>
```
```js
import { defineComponent, ref } from 'vue'
import { defineComponent } from 'vue'
export default defineComponent({
setup () {
return {
active: ref(true)
railStyle: ({ focused, checked }) => {
const style = {}
if (checked) {
style.background = '#d03050'
if (focused) {
style.boxShadow = '0 0 0 2px #d0305040'
}
} else {
style.background = '#2080f0'
if (focused) {
style.boxShadow = '0 0 0 2px #2080f40'
}
}
return style
}
}
}
})

View File

@ -25,15 +25,12 @@ color
| default-value | `boolean` | `false` | 非受控模式下的默认值 |
| disabled | `boolean` | `false` | 是否禁用 |
| loading | `boolean` | `false` | 是否加载 |
| rail-style | `(info: { focused: boolean, checked: boolean }) => (CSSProperties \| string)` | `undefined` | 创建轨道样式的函数 |
| round | `boolean` | `true` | 是否为圆形按钮 |
| size | `'small' \| 'medium' \| 'large'` | `'medium'` | 开关大小 |
| unchecked-value | `string \| boolean \| number` | `false` | 未选中时对应的值 |
| value | `boolean` | `undefined` | 受控模式下的值 |
| on-update:value | `(value: boolean) => void` | `undefined` | 组件值发生变化的回调 |
| activeColor | `string` | `undefined` | 选中时对应的背景色 |
| inactiveColor | `string` | `undefined` | 未选中时对应的背景色 |
| activeButtonColor | `string` | `undefined` | 选中时对应的按钮颜色 |
| inactiveButtonColor | `string` | `undefined` | 未选中时对应的按钮颜色 |
### Switch Slots

View File

@ -56,14 +56,11 @@ const switchProps = {
type: [String, Number, Boolean] as PropType<string | number | boolean>,
default: false
},
/** @deprecated */
onChange: [Function, Array] as PropType<
MaybeArray<OnUpdateValue> | undefined
railStyle: Function as PropType<
(params: { focused: boolean, checked: boolean }) => string | CSSProperties
>,
activeColor: String,
inactiveColor: String,
activeButtonColor: String,
inactiveButtonColor: String
/** @deprecated */
onChange: [Function, Array] as PropType<MaybeArray<OnUpdateValue> | undefined>
} as const
export type SwitchProps = ExtractPublicPropTypes<typeof switchProps>
@ -99,7 +96,16 @@ export default defineComponent({
controlledValueRef,
uncontrolledValueRef
)
const checkedRef = computed(() => {
return mergedValueRef.value === props.checkedValue
})
const pressedRef = ref(false)
const focusedRef = ref(false)
const mergedRailStyleRef = computed(() => {
const { railStyle } = props
if (!railStyle) return undefined
return railStyle({ focused: focusedRef.value, checked: checkedRef.value })
})
function doUpdateValue (value: string | number | boolean): void {
const {
'onUpdate:value': _onUpdateValue,
@ -132,9 +138,11 @@ export default defineComponent({
}
}
function handleFocus (): void {
focusedRef.value = true
doFocus()
}
function handleBlur (): void {
focusedRef.value = false
doBlur()
pressedRef.value = false
}
@ -156,9 +164,11 @@ export default defineComponent({
handleFocus,
handleKeyup,
handleKeydown,
mergedRailStyle: mergedRailStyleRef,
pressed: pressedRef,
mergedClsPrefix: mergedClsPrefixRef,
mergedValue: mergedValueRef,
checked: checkedRef,
mergedDisabled: mergedDisabledRef,
cssVars: computed(() => {
const { value: size } = mergedSizeRef
@ -215,12 +225,11 @@ export default defineComponent({
render () {
const {
mergedClsPrefix,
mergedValue,
mergedDisabled,
checkedValue,
checked,
mergedRailStyle,
$slots
} = this
const checked = mergedValue === checkedValue
const { checked: checkedSlot, unchecked: uncheckedSlot } = $slots
return (
<div
@ -244,11 +253,7 @@ export default defineComponent({
<div
class={`${mergedClsPrefix}-switch__rail`}
aria-hidden="true"
style={
this.activeColor || this.inactiveColor
? { background: checked ? this.activeColor : this.inactiveColor }
: {}
}
style={mergedRailStyle}
>
{(checkedSlot || uncheckedSlot) && (
<div
@ -265,18 +270,7 @@ export default defineComponent({
</div>
</div>
)}
<div
class={`${mergedClsPrefix}-switch__button`}
style={
this.activeButtonColor || this.inactiveButtonColor
? {
background: checked
? this.activeButtonColor
: this.inactiveButtonColor
}
: {}
}
>
<div class={`${mergedClsPrefix}-switch__button`}>
<Transition name="fade-in-scale-up-transition">
{{
default: () =>