| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- import React from 'react';
- import PropTypes from 'prop-types';
- import RadioInnerFoundation, { RadioChangeEvent, RadioInnerAdapter } from '@douyinfe/semi-foundation/radio/radioInnerFoundation';
- import BaseComponent, { BaseProps } from '../_base/baseComponent';
- import { radioClasses as css } from '@douyinfe/semi-foundation/radio/constants';
- import Context from './context';
- import classnames from 'classnames';
- import { IconRadio } from '@douyinfe/semi-icons';
- import { noop } from 'lodash';
- export type RadioInnerMode = 'advanced' | '';
- export interface RadioInnerProps extends BaseProps {
- checked?: boolean;
- disabled?: boolean;
- isButtonRadio?: boolean;
- onChange?: (e: RadioChangeEvent) => void;
- mode?: RadioInnerMode;
- autoFocus?: boolean;
- name?: string;
- prefixCls?: string;
- ref?: React.MutableRefObject<RadioInner> | ((instance: RadioInner) => void);
- isPureCardRadioGroup?: boolean;
- addonId?: string;
- extraId?: string;
- 'aria-label'?: React.AriaAttributes['aria-label'];
- focusInner?: boolean;
- onInputFocus?: (e: any) => void;
- onInputBlur?: (e: any) => void;
- preventScroll?: boolean;
- }
- interface RadioInnerState {
- checked?: boolean;
- }
- class RadioInner extends BaseComponent<RadioInnerProps, RadioInnerState> {
- static contextType = Context;
- static propTypes = {
- checked: PropTypes.bool,
- disabled: PropTypes.bool,
- isButtonRadio: PropTypes.bool,
- onChange: PropTypes.func,
- mode: PropTypes.oneOf(['advanced', '']),
- 'aria-label': PropTypes.string,
- focusInner: PropTypes.bool,
- onInputFocus: PropTypes.func,
- onInputBlur: PropTypes.func,
- preventScroll: PropTypes.bool,
- };
- static defaultProps = {
- onChange: noop,
- isButtonRadio: false
- };
- inputEntity!: HTMLInputElement;
- foundation: RadioInnerFoundation;
- constructor(props: RadioInnerProps) {
- super(props);
- this.state = {
- checked: false
- };
- this.foundation = new RadioInnerFoundation(this.adapter);
- this.onChange = this.onChange.bind(this);
- }
- get adapter(): RadioInnerAdapter {
- return {
- ...super.adapter,
- setNativeControlChecked: (checked: boolean) => {
- this.setState({ checked });
- },
- notifyChange: (e: RadioChangeEvent) => {
- this.props.onChange(e);
- }
- };
- }
- componentDidMount() {
- this.foundation.init();
- }
- componentDidUpdate(prevProps: RadioInnerProps) {
- if (prevProps.checked !== this.props.checked) {
- this.foundation.setChecked(this.props.checked);
- }
- }
- componentWillUnmount() {
- this.foundation.destroy();
- }
- blur() {
- this.inputEntity.blur();
- }
- focus() {
- const { preventScroll } = this.props;
- this.inputEntity.focus({ preventScroll });
- }
- onChange(e: React.ChangeEvent<HTMLInputElement>) {
- this.foundation.handleChange(e);
- }
- render() {
- const { disabled, mode, autoFocus, name, isButtonRadio, isPureCardRadioGroup, addonId, extraId, 'aria-label': ariaLabel, focusInner, onInputFocus, onInputBlur } = this.props;
- const { checked } = this.state;
- const prefix = this.props.prefixCls || css.PREFIX;
- const wrapper = classnames({
- [`${prefix}-inner`]: true,
- [`${prefix}-inner-checked`]: Boolean(checked),
- [`${prefix}-inner-buttonRadio`]: isButtonRadio,
- [`${prefix}-inner-pureCardRadio`]: isPureCardRadioGroup,
- });
- const inner = classnames({
- [`${prefix}-focus`]: focusInner,
- [`${prefix}-focus-border`]: focusInner && !checked,
- [`${prefix}-inner-display`]: !isButtonRadio,
- });
- return (
- <span className={wrapper}>
- <input
- ref={ref => {
- this.inputEntity = ref;
- }}
- autoFocus={autoFocus}
- type={mode === 'advanced' ? 'checkbox' : 'radio'}
- checked={Boolean(checked)}
- disabled={disabled}
- onChange={this.onChange}
- name={name}
- aria-label={ariaLabel}
- aria-labelledby={addonId}
- aria-describedby={extraId}
- onFocus={onInputFocus}
- onBlur={onInputBlur}
- />
- <span className={inner}>{checked ? <IconRadio /> : null}</span>
- </span>
- );
- }
- }
- export default RadioInner;
|