feat: update switch (#2439)
* feat: update switch * fix: avoid bind attrs to root * test: update switch * docs: update switch breakchange * style: remove unused import Co-authored-by: tangjinzhou <415800467@qq.com>pull/2494/head
							parent
							
								
									ae7e792f0a
								
							
						
					
					
						commit
						6f903c3a75
					
				| 
						 | 
				
			
			@ -59,3 +59,7 @@ v-model -> v-model:checked
 | 
			
		|||
checkboxGroup
 | 
			
		||||
 | 
			
		||||
v-model -> v-model:value
 | 
			
		||||
 | 
			
		||||
## Switch
 | 
			
		||||
 | 
			
		||||
v-model -> v-model:checked
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,6 @@
 | 
			
		|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
 | 
			
		||||
 | 
			
		||||
exports[`Switch should has click wave effect 1`] = `<button type="button" role="switch" class="ant-switch ant-switch-checked" aria-checked="true"><span class="ant-switch-inner"></span></button>`;
 | 
			
		||||
exports[`Switch should has click wave effect 1`] = `
 | 
			
		||||
<button class="ant-switch ant-switch-checked" type="button" role="switch" aria-checked="true">
 | 
			
		||||
  <!----><span class="ant-switch-inner"><!----></span></button>
 | 
			
		||||
`;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,7 +19,7 @@ describe('Switch', () => {
 | 
			
		|||
    resetWarned();
 | 
			
		||||
 | 
			
		||||
    const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
 | 
			
		||||
    mount(Switch, { propsData: { value: '' } });
 | 
			
		||||
    mount(Switch, { props: { value: '' } });
 | 
			
		||||
    expect(errorSpy).toHaveBeenCalledWith(
 | 
			
		||||
      'Warning: [antdv: Switch] `value` is not validate prop, do you mean `checked`?',
 | 
			
		||||
    );
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,19 +1,17 @@
 | 
			
		|||
import { inject } from 'vue';
 | 
			
		||||
import LoadingOutlined from '@ant-design/icons-vue/LoadingOutlined';
 | 
			
		||||
import PropTypes from '../_util/vue-types';
 | 
			
		||||
import hasProp, { getOptionProps, getComponentFromProp, getListeners } from '../_util/props-util';
 | 
			
		||||
import hasProp, { getOptionProps, getComponent } from '../_util/props-util';
 | 
			
		||||
import VcSwitch from '../vc-switch';
 | 
			
		||||
import Wave from '../_util/wave';
 | 
			
		||||
import { ConfigConsumerProps } from '../config-provider';
 | 
			
		||||
import Base from '../base';
 | 
			
		||||
import warning from '../_util/warning';
 | 
			
		||||
import createRefHooks from '../_util/createRefHooks';
 | 
			
		||||
 | 
			
		||||
const Switch = {
 | 
			
		||||
  name: 'ASwitch',
 | 
			
		||||
  __ANT_SWITCH: true,
 | 
			
		||||
  model: {
 | 
			
		||||
    prop: 'checked',
 | 
			
		||||
    event: 'change',
 | 
			
		||||
  },
 | 
			
		||||
  inheritAttrs: false,
 | 
			
		||||
  props: {
 | 
			
		||||
    prefixCls: PropTypes.string,
 | 
			
		||||
    // size=default and size=large are the same
 | 
			
		||||
| 
						 | 
				
			
			@ -27,20 +25,25 @@ const Switch = {
 | 
			
		|||
    autoFocus: PropTypes.bool,
 | 
			
		||||
    loading: PropTypes.bool,
 | 
			
		||||
  },
 | 
			
		||||
  inject: {
 | 
			
		||||
    configProvider: { default: () => ConfigConsumerProps },
 | 
			
		||||
  setup() {
 | 
			
		||||
    return {
 | 
			
		||||
      configProvider: inject('configProvider', ConfigConsumerProps),
 | 
			
		||||
    };
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    focus() {
 | 
			
		||||
      this.$refs.refSwitchNode.focus();
 | 
			
		||||
      this.refSwitchNode?.ctx?.focus();
 | 
			
		||||
    },
 | 
			
		||||
    blur() {
 | 
			
		||||
      this.$refs.refSwitchNode.blur();
 | 
			
		||||
      this.refSwitchNode?.ctx?.blur();
 | 
			
		||||
    },
 | 
			
		||||
    saveRef(c) {
 | 
			
		||||
      this.refSwitchNode = c;
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  created() {
 | 
			
		||||
    warning(
 | 
			
		||||
      hasProp(this, 'checked') || !hasProp(this, 'value'),
 | 
			
		||||
      hasProp(this, 'checked') || !('value' in this.$attrs),
 | 
			
		||||
      'Switch',
 | 
			
		||||
      '`value` is not validate prop, do you mean `checked`?',
 | 
			
		||||
    );
 | 
			
		||||
| 
						 | 
				
			
			@ -52,27 +55,26 @@ const Switch = {
 | 
			
		|||
    );
 | 
			
		||||
    const getPrefixCls = this.configProvider.getPrefixCls;
 | 
			
		||||
    const prefixCls = getPrefixCls('switch', customizePrefixCls);
 | 
			
		||||
    const { $attrs } = this;
 | 
			
		||||
 | 
			
		||||
    const classes = {
 | 
			
		||||
      [$attrs.class]: $attrs.class,
 | 
			
		||||
      [`${prefixCls}-small`]: size === 'small',
 | 
			
		||||
      [`${prefixCls}-loading`]: loading,
 | 
			
		||||
    };
 | 
			
		||||
    const loadingIcon = loading ? (
 | 
			
		||||
      <LoadingOutlined class={`${prefixCls}-loading-icon`} />
 | 
			
		||||
    ) : null;
 | 
			
		||||
    const loadingIcon = loading ? <LoadingOutlined class={`${prefixCls}-loading-icon`} /> : null;
 | 
			
		||||
    const switchProps = {
 | 
			
		||||
      props: {
 | 
			
		||||
        ...restProps,
 | 
			
		||||
        prefixCls,
 | 
			
		||||
        loadingIcon,
 | 
			
		||||
        checkedChildren: getComponentFromProp(this, 'checkedChildren'),
 | 
			
		||||
        unCheckedChildren: getComponentFromProp(this, 'unCheckedChildren'),
 | 
			
		||||
        disabled: disabled || loading,
 | 
			
		||||
      },
 | 
			
		||||
      on: getListeners(this),
 | 
			
		||||
      ...restProps,
 | 
			
		||||
      prefixCls,
 | 
			
		||||
      loadingIcon,
 | 
			
		||||
      checkedChildren: getComponent(this, 'checkedChildren'),
 | 
			
		||||
      unCheckedChildren: getComponent(this, 'unCheckedChildren'),
 | 
			
		||||
      disabled: disabled || loading,
 | 
			
		||||
      ...$attrs,
 | 
			
		||||
      class: classes,
 | 
			
		||||
      ref: 'refSwitchNode',
 | 
			
		||||
      ...createRefHooks(this.saveRef),
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
      <Wave insertExtraNode>
 | 
			
		||||
        <VcSwitch {...switchProps} />
 | 
			
		||||
| 
						 | 
				
			
			@ -82,9 +84,8 @@ const Switch = {
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
/* istanbul ignore next */
 | 
			
		||||
Switch.install = function(Vue) {
 | 
			
		||||
  Vue.use(Base);
 | 
			
		||||
  Vue.component(Switch.name, Switch);
 | 
			
		||||
Switch.install = function(app) {
 | 
			
		||||
  app.component(Switch.name, Switch);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default Switch;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,7 +9,7 @@ export const switchPropTypes = {
 | 
			
		|||
  // onMouseUp: PropTypes.func,
 | 
			
		||||
  // onClick: PropTypes.func,
 | 
			
		||||
  tabIndex: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
 | 
			
		||||
  checked: PropTypes.bool.def(false),
 | 
			
		||||
  checked: PropTypes.bool,
 | 
			
		||||
  defaultChecked: PropTypes.bool.def(false),
 | 
			
		||||
  autoFocus: PropTypes.bool.def(false),
 | 
			
		||||
  loadingIcon: PropTypes.any,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,16 +1,14 @@
 | 
			
		|||
import { switchPropTypes } from './PropTypes';
 | 
			
		||||
import BaseMixin from '../_util/BaseMixin';
 | 
			
		||||
import { hasProp, getOptionProps, getComponentFromProp, getListeners } from '../_util/props-util';
 | 
			
		||||
import { hasProp, getOptionProps, getComponent } from '../_util/props-util';
 | 
			
		||||
import createRefHooks from '../_util/createRefHooks';
 | 
			
		||||
 | 
			
		||||
// function noop () {
 | 
			
		||||
// }
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'VcSwitch',
 | 
			
		||||
  mixins: [BaseMixin],
 | 
			
		||||
  model: {
 | 
			
		||||
    prop: 'checked',
 | 
			
		||||
    event: 'change',
 | 
			
		||||
  },
 | 
			
		||||
  inheritAttrs: false,
 | 
			
		||||
  props: {
 | 
			
		||||
    ...switchPropTypes,
 | 
			
		||||
    prefixCls: switchPropTypes.prefixCls.def('rc-switch'),
 | 
			
		||||
| 
						 | 
				
			
			@ -42,6 +40,9 @@ export default {
 | 
			
		|||
    });
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    saveRef(c) {
 | 
			
		||||
      this.refSwitchNode = c;
 | 
			
		||||
    },
 | 
			
		||||
    setChecked(checked, e) {
 | 
			
		||||
      if (this.disabled) {
 | 
			
		||||
        return;
 | 
			
		||||
| 
						 | 
				
			
			@ -50,6 +51,7 @@ export default {
 | 
			
		|||
        this.stateChecked = checked;
 | 
			
		||||
      }
 | 
			
		||||
      this.$emit('change', checked, e);
 | 
			
		||||
      this.$emit('update:checked', checked);
 | 
			
		||||
    },
 | 
			
		||||
    handleClick(e) {
 | 
			
		||||
      const checked = !this.stateChecked;
 | 
			
		||||
| 
						 | 
				
			
			@ -66,51 +68,55 @@ export default {
 | 
			
		|||
      }
 | 
			
		||||
    },
 | 
			
		||||
    handleMouseUp(e) {
 | 
			
		||||
      if (this.$refs.refSwitchNode) {
 | 
			
		||||
        this.$refs.refSwitchNode.blur();
 | 
			
		||||
      }
 | 
			
		||||
      this.refSwitchNode?.blur();
 | 
			
		||||
 | 
			
		||||
      this.$emit('mouseup', e);
 | 
			
		||||
    },
 | 
			
		||||
    focus() {
 | 
			
		||||
      this.$refs.refSwitchNode.focus();
 | 
			
		||||
      this.refSwitchNode?.focus();
 | 
			
		||||
    },
 | 
			
		||||
    blur() {
 | 
			
		||||
      this.$refs.refSwitchNode.blur();
 | 
			
		||||
      this.refSwitchNode?.blur();
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  render() {
 | 
			
		||||
    const { prefixCls, disabled, loadingIcon, tabIndex, ...restProps } = getOptionProps(this);
 | 
			
		||||
    const {
 | 
			
		||||
      prefixCls,
 | 
			
		||||
      disabled,
 | 
			
		||||
      loadingIcon,
 | 
			
		||||
      defaultChecked,
 | 
			
		||||
      autoFocus,
 | 
			
		||||
      ...restProps
 | 
			
		||||
    } = getOptionProps(this);
 | 
			
		||||
    const checked = this.stateChecked;
 | 
			
		||||
    const { $attrs } = this;
 | 
			
		||||
    const switchClassName = {
 | 
			
		||||
      [$attrs.class]: $attrs.class,
 | 
			
		||||
      [prefixCls]: true,
 | 
			
		||||
      [`${prefixCls}-checked`]: checked,
 | 
			
		||||
      [`${prefixCls}-disabled`]: disabled,
 | 
			
		||||
    };
 | 
			
		||||
    const spanProps = {
 | 
			
		||||
      props: { ...restProps },
 | 
			
		||||
      on: {
 | 
			
		||||
        ...getListeners(this),
 | 
			
		||||
        keydown: this.handleKeyDown,
 | 
			
		||||
        click: this.handleClick,
 | 
			
		||||
        mouseup: this.handleMouseUp,
 | 
			
		||||
      },
 | 
			
		||||
      attrs: {
 | 
			
		||||
        type: 'button',
 | 
			
		||||
        role: 'switch',
 | 
			
		||||
        'aria-checked': checked,
 | 
			
		||||
        disabled,
 | 
			
		||||
        tabIndex,
 | 
			
		||||
      },
 | 
			
		||||
      ...restProps,
 | 
			
		||||
      ...$attrs,
 | 
			
		||||
      onKeydown: this.handleKeyDown,
 | 
			
		||||
      onClick: this.handleClick,
 | 
			
		||||
      onMouseup: this.handleMouseUp,
 | 
			
		||||
      type: 'button',
 | 
			
		||||
      role: 'switch',
 | 
			
		||||
      'aria-checked': checked,
 | 
			
		||||
      disabled,
 | 
			
		||||
      class: switchClassName,
 | 
			
		||||
      ref: 'refSwitchNode',
 | 
			
		||||
      ...createRefHooks(this.saveRef),
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
      <button {...spanProps}>
 | 
			
		||||
        {loadingIcon}
 | 
			
		||||
        <span class={`${prefixCls}-inner`}>
 | 
			
		||||
          {checked
 | 
			
		||||
            ? getComponentFromProp(this, 'checkedChildren')
 | 
			
		||||
            : getComponentFromProp(this, 'unCheckedChildren')}
 | 
			
		||||
            ? getComponent(this, 'checkedChildren')
 | 
			
		||||
            : getComponent(this, 'unCheckedChildren')}
 | 
			
		||||
        </span>
 | 
			
		||||
      </button>
 | 
			
		||||
    );
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,8 +35,8 @@ import Menu from 'ant-design-vue/menu';
 | 
			
		|||
import Mentions from 'ant-design-vue/mentions';
 | 
			
		||||
import Dropdown from 'ant-design-vue/dropdown';
 | 
			
		||||
import Steps from 'ant-design-vue/steps';
 | 
			
		||||
import Switch from 'ant-design-vue/switch';
 | 
			
		||||
import Layout from 'ant-design-vue/layout';
 | 
			
		||||
 | 
			
		||||
import 'ant-design-vue/style.js';
 | 
			
		||||
 | 
			
		||||
const basic = {
 | 
			
		||||
| 
						 | 
				
			
			@ -85,5 +85,6 @@ app
 | 
			
		|||
  .use(Mentions)
 | 
			
		||||
  .use(Dropdown)
 | 
			
		||||
  .use(Steps)
 | 
			
		||||
  .use(Switch)
 | 
			
		||||
  .use(Layout)
 | 
			
		||||
  .mount('#app');
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue