All files / src/radio RadioGroup.tsx

44.44% Statements 8/18
43.75% Branches 7/16
66.67% Functions 2/3
44.44% Lines 8/18

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 94 95                                                                                            13x       13x     40x       40x       40x 40x               40x                                       13x        
import React from "react";
import invariant from "invariant";
import { ControlledProps, useDefaultValue } from "../form/controlled";
import { CheckContext, CheckContextValue, CheckChangeContext } from "../check";
 
/**
 * RadioGroup 组件所接收的属性
 */
export interface RadioGroupProps extends ControlledProps<string> {
  /**
   * 当前选中的 Radio 的 name
   */
  value?: string;
 
  /**
   * 值变更时回调
   */
  onChange?: (value: string, context: CheckChangeContext) => void;
 
  /**
   * 禁用组件
   * @default false
   */
  disabled?: boolean;
 
  /**
   * 使用水平布局(inline)还是纵向排列布局(column)
   * @default "inline"
   */
  layout?: "inline" | "column";
 
  /**
   * 单选按钮内容
   */
  children?: React.ReactNode;
}
 
export interface RadioGroupTarget {
  /** 当前选中的 Radio 的值 */
  value: string;
}
 
/**
 * 单选选项组,里面可以嵌套 <Radio />
 */
export function RadioGroup(props: RadioGroupProps) {
  const { disabled, layout, children, value, onChange } = useDefaultValue(
    props
  );
 
  const context: CheckContextValue = {
    inject: checkProps => {
      // 只为 radio 提供
      Iif (checkProps.type !== "radio") {
        return checkProps;
      }
      // 如果已经受控,则不注入
      Iif (typeof checkProps.value === "boolean") {
        return checkProps;
      }
 
      const checkName = checkProps.name;
      Iif (typeof checkName === "undefined") {
        invariant(
          false,
          '<Radio> managed by <RadioGroup> must include the "name" prop'
        );
        return checkProps;
      }
 
      return {
        ...checkProps,
        value: value === checkProps.name,
        disabled: checkProps.disabled || disabled,
        display: layout === "column" ? "block" : "inline",
        onChange(checked, context) {
          if (typeof checkProps.onChange === "function") {
            checkProps.onChange(checked, context);
            if (context.event.defaultPrevented) {
              return;
            }
          }
          if (typeof onChange === "function") {
            onChange(checkName, context);
          }
        },
      };
    },
  };
 
  return (
    <CheckContext.Provider value={context}>{children}</CheckContext.Provider>
  );
}