[React Ocean 组件库] 实现 Radio 单选题

310 阅读1分钟

交互展示

1b2601ec-b990-4a50-9e51-b08c13f5de94.gif

image.png

image.png

使用

const RadioDemo1 = () => {
  const [value, setValue] = useState(1);

  const onChange = (value: any) => {
    setValue(value);
  };

  return (
      <RadioGroup onChange={onChange} value={value}>
        <Radio value={1}>A</Radio>
        <Radio value={2}>B</Radio>
        <Radio value={3}>C</Radio>
        <Radio value={4}>D</Radio>
      </RadioGroup>
    </div>
  );
};

需求

  • 支持不同方向,不同大小,不同类型的单选按钮。
  • 实心单选题按钮。

实现

思路:Radio 主要是复用了 ButtonBasetype, 以及 ButtonBase 的 波浪动画。 根据 CSS in JS 做定制化。

const Radio = (props: Radio) => {
  const RadioContext = useRadioContext();
  const isSelect = props.value === RadioContext?.value;
  const isText = RadioContext?.type === 'text';

  const isDanger = RadioContext?.type === 'danger';

  const computedSize = (size = 'medium'): [string, string] => {
    let dimension = '35px';
    let fontSize = GlobalFontSize.medium;
    if (size === 'large') {
      dimension = GlobalRadioSize.large;
      fontSize = GlobalFontSize.large;
    } else if (size === 'small') {
      dimension = GlobalRadioSize.small;
      fontSize = GlobalFontSize.small;
    }
    return [dimension, fontSize];
  };

  const [size, fontSize] = computedSize(RadioContext?.size);

  const radioClick = (
    e: React.MouseEvent<HTMLElement, MouseEvent>,
    value: any,
  ) => {
    RadioContext?.onChange(e, value);
  };

  return (
    <>
      <RadioWrapper
        isSelect={isSelect}
        onClick={(e) => radioClick(e, props.value)}
        size={{ size: size, fontSize: fontSize }}
        isText={isText}
        isDanger={isDanger}
      >
        <ButtonBase
          type={isSelect ? RadioContext.type || 'primary' : 'outline'}
          height={size}
          animationColor={isDanger ? TypeButtonColor.dangerRippleColor : ''}
        >
          {props.children}
        </ButtonBase>
      </RadioWrapper>
    </>
  );
};