84 lines
2.3 KiB
TypeScript
84 lines
2.3 KiB
TypeScript
import React from "react";
|
|
import styled from "styled-components";
|
|
import { WidgetProps } from "@rjsf/core";
|
|
import RadioButton from "./RadioButton";
|
|
|
|
type RadioButtonWidgetProps = Omit<WidgetProps, "options"> & {
|
|
options: {
|
|
enumOptions: {
|
|
value: string;
|
|
label: string;
|
|
}[];
|
|
enumDisabled: string[];
|
|
inline: boolean;
|
|
};
|
|
};
|
|
|
|
const RadioButtonContainer = styled.div`
|
|
margin-bottom: 1rem;
|
|
`;
|
|
|
|
const RadioButtonWidget: React.FC<RadioButtonWidgetProps> = (props) => {
|
|
const {
|
|
options,
|
|
value,
|
|
required,
|
|
disabled,
|
|
readonly,
|
|
autofocus,
|
|
onBlur,
|
|
onFocus,
|
|
onChange,
|
|
id,
|
|
} = props;
|
|
// Generating a unique field name to identify this set of radio buttons
|
|
const name = Math.random().toString();
|
|
const { enumOptions, enumDisabled, inline } = options;
|
|
// checked={checked} has been moved above name={name}, As mentioned in #349;
|
|
// this is a temporary fix for radio button rendering bug in React, facebook/react#7630.
|
|
return (
|
|
<div className="field-radio-group" id={id}>
|
|
{enumOptions.map((option, index) => {
|
|
const key = `${id}_${index}`;
|
|
const checked = option.value === value;
|
|
const itemDisabled =
|
|
enumDisabled && enumDisabled.indexOf(option.value) !== -1;
|
|
const disabledCls =
|
|
disabled || itemDisabled || readonly ? "disabled" : "";
|
|
const radio = (
|
|
<RadioButton
|
|
checked={checked}
|
|
name={name}
|
|
required={required}
|
|
value={option.value}
|
|
disabled={disabled || itemDisabled || readonly}
|
|
// eslint-disable-next-line jsx-a11y/no-autofocus
|
|
autoFocus={autofocus && index === 0}
|
|
onChange={() => onChange(option.value)}
|
|
onBlur={onBlur && ((event) => onBlur(id, event.target.value))}
|
|
onFocus={onFocus && ((event) => onFocus(id, event.target.value))}
|
|
>
|
|
{option.label}
|
|
</RadioButton>
|
|
);
|
|
|
|
return inline ? (
|
|
<label key={key} className={`radio-inline ${disabledCls}`}>
|
|
{radio}
|
|
</label>
|
|
) : (
|
|
<RadioButtonContainer key={key} className={disabledCls}>
|
|
{radio}
|
|
</RadioButtonContainer>
|
|
);
|
|
})}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
RadioButtonWidget.defaultProps = {
|
|
autofocus: false,
|
|
};
|
|
|
|
export default RadioButtonWidget;
|