feat(Form): support using switch
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
// Utils
|
||||
import { createNamespace, addUnit } from '../utils';
|
||||
import { BLUE } from '../utils/constant';
|
||||
import { switchProps } from './shared';
|
||||
|
||||
// Mixins
|
||||
import { FieldMixin } from '../mixins/field';
|
||||
|
||||
// Components
|
||||
import Loading from '../loading';
|
||||
|
||||
const [createComponent, bem] = createNamespace('switch');
|
||||
|
||||
export default createComponent({
|
||||
mixins: [FieldMixin],
|
||||
|
||||
props: switchProps,
|
||||
|
||||
computed: {
|
||||
checked() {
|
||||
return this.value === this.activeValue;
|
||||
},
|
||||
|
||||
style() {
|
||||
return {
|
||||
fontSize: addUnit(this.size),
|
||||
backgroundColor: this.checked ? this.activeColor : this.inactiveColor,
|
||||
};
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
onClick(event) {
|
||||
this.$emit('click', event);
|
||||
|
||||
if (!this.disabled && !this.loading) {
|
||||
const newValue = this.checked ? this.inactiveValue : this.activeValue;
|
||||
this.$emit('input', newValue);
|
||||
this.$emit('change', newValue);
|
||||
}
|
||||
},
|
||||
|
||||
genLoading() {
|
||||
if (this.loading) {
|
||||
const color = this.checked
|
||||
? this.activeColor || BLUE
|
||||
: this.inactiveColor || '';
|
||||
|
||||
return <Loading class={bem('loading')} color={color} />;
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
render() {
|
||||
const { checked, loading, disabled } = this;
|
||||
|
||||
return (
|
||||
<div
|
||||
class={bem({
|
||||
on: checked,
|
||||
loading,
|
||||
disabled,
|
||||
})}
|
||||
role="switch"
|
||||
style={this.style}
|
||||
aria-checked={String(checked)}
|
||||
onClick={this.onClick}
|
||||
>
|
||||
<div class={bem('node')}>{this.genLoading()}</div>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
});
|
||||
@@ -1,78 +0,0 @@
|
||||
// Utils
|
||||
import { createNamespace, addUnit } from '../utils';
|
||||
import { BLUE } from '../utils/constant';
|
||||
import { emit, inherit } from '../utils/functional';
|
||||
import { switchProps, SharedSwitchProps } from './shared';
|
||||
|
||||
// Components
|
||||
import Loading from '../loading';
|
||||
|
||||
// Types
|
||||
import { CreateElement, RenderContext } from 'vue/types';
|
||||
import { DefaultSlots } from '../utils/types';
|
||||
|
||||
export type SwitchEvents = {
|
||||
onChange?(checked: boolean): void;
|
||||
};
|
||||
|
||||
const [createComponent, bem] = createNamespace('switch');
|
||||
|
||||
function Switch(
|
||||
h: CreateElement,
|
||||
props: SharedSwitchProps,
|
||||
slots: DefaultSlots,
|
||||
ctx: RenderContext<SharedSwitchProps>
|
||||
) {
|
||||
const {
|
||||
size,
|
||||
value,
|
||||
loading,
|
||||
disabled,
|
||||
activeColor,
|
||||
activeValue,
|
||||
inactiveColor,
|
||||
inactiveValue,
|
||||
} = props;
|
||||
|
||||
const checked = value === activeValue;
|
||||
|
||||
const switchStyle = {
|
||||
fontSize: addUnit(size),
|
||||
backgroundColor: checked ? activeColor : inactiveColor,
|
||||
};
|
||||
|
||||
const loadingColor = checked ? activeColor || BLUE : inactiveColor || '';
|
||||
|
||||
function onClick(event: PointerEvent) {
|
||||
emit(ctx, 'click', event);
|
||||
|
||||
if (!disabled && !loading) {
|
||||
const newValue = checked ? inactiveValue : activeValue;
|
||||
emit(ctx, 'input', newValue);
|
||||
emit(ctx, 'change', newValue);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
class={bem({
|
||||
on: checked,
|
||||
loading,
|
||||
disabled,
|
||||
})}
|
||||
role="switch"
|
||||
style={switchStyle}
|
||||
aria-checked={String(checked)}
|
||||
onClick={onClick}
|
||||
{...inherit(ctx)}
|
||||
>
|
||||
<div class={bem('node')}>
|
||||
{loading && <Loading class={bem('loading')} color={loadingColor} />}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Switch.props = switchProps;
|
||||
|
||||
export default createComponent<SharedSwitchProps, SwitchEvents>(Switch);
|
||||
@@ -5,11 +5,9 @@ test('emit event', () => {
|
||||
const input = jest.fn();
|
||||
const change = jest.fn();
|
||||
const wrapper = mount(Switch, {
|
||||
context: {
|
||||
on: {
|
||||
input,
|
||||
change,
|
||||
},
|
||||
listeners: {
|
||||
input,
|
||||
change,
|
||||
},
|
||||
});
|
||||
wrapper.trigger('click');
|
||||
@@ -22,11 +20,9 @@ test('disabled', () => {
|
||||
const input = jest.fn();
|
||||
const change = jest.fn();
|
||||
const wrapper = mount(Switch, {
|
||||
context: {
|
||||
on: {
|
||||
input,
|
||||
change,
|
||||
},
|
||||
listeners: {
|
||||
input,
|
||||
change,
|
||||
},
|
||||
propsData: {
|
||||
disabled: true,
|
||||
@@ -47,11 +43,9 @@ test('active-value & inactive-value prop', () => {
|
||||
activeValue: '1',
|
||||
inactiveValue: '2',
|
||||
},
|
||||
context: {
|
||||
on: {
|
||||
input,
|
||||
change,
|
||||
},
|
||||
listeners: {
|
||||
input,
|
||||
change,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -86,10 +80,8 @@ test('size prop', () => {
|
||||
test('click event', () => {
|
||||
const click = jest.fn();
|
||||
const wrapper = mount(Switch, {
|
||||
context: {
|
||||
on: {
|
||||
click,
|
||||
},
|
||||
listeners: {
|
||||
click,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user