All files / src/switch Switch.tsx

85.71% Statements 12/14
88.89% Branches 8/9
33.33% Functions 1/3
85.71% Lines 12/14

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93                                        14x     47x   47x   47x   10x                     47x     47x                                                         47x 42x                         47x 2x     47x    
import React, { useContext } from "react";
import classNames from "classnames";
import { Omit } from "../_type";
import { CheckProps, CheckContext } from "../check";
import { Text } from "../text";
import { useDefaultValue } from "../form/controlled";
import { callBoth } from "../_util/call-both";
import { Tooltip } from "../tooltip";
import { useConfig } from "../_util/config-context";
 
/**
 * Switch 组件所接收的参数
 */
export interface SwitchProps extends Omit<CheckProps, "type"> {
  /**
   * 是否繁忙
   */
  loading?: boolean;
}
 
const noop = () => {};
 
export function Switch(props: SwitchProps) {
  const { classPrefix } = useConfig();
  // 支持从 Context 注入
  const context = useContext(CheckContext);
 
  if (context) {
    // eslint-disable-next-line no-param-reassign
    props = context.inject({ type: "checkbox", ...props });
  }
 
  const {
    value,
    disabled,
    onChange = noop,
    onClick,
    loading,
    tooltip,
    children,
  } = useDefaultValue(props, false);
 
  let component = (
    <label
      className={classNames(`${classPrefix}-switch`, { "is-loading": loading })}
    >
      <input
        readOnly
        type="checkbox"
        className={`${classPrefix}-switch__input`}
        checked={value}
        disabled={disabled}
        onClick={callBoth(
          onClick,
          (event: React.MouseEvent<HTMLInputElement>) => {
            const { checked } = event.currentTarget;
            onChange(checked, {
              event,
              check: {
                type: "checkbox",
                ...props,
                value: checked,
              },
            });
          }
        )}
      />
      <span className={`${classPrefix}-switch__toggle`} />
    </label>
  );
 
  // 默认是不需要 children 的,如果提供了,需要包装一层
  if (children) {
    component = (
      <label
        onClick={onClick}
        style={{ cursor: disabled ? "default" : "pointer" }}
      >
        {component}
        <Text reset style={{ verticalAlign: "middle", margin: "0 5px" }}>
          {children}
        </Text>
      </label>
    );
  }
 
  if (tooltip) {
    component = <Tooltip title={tooltip}>{component}</Tooltip>;
  }
 
  return component;
}