@syncfusion/react-buttons
Version:
Syncfusion React Buttons package is a feature-rich collection of UI components including Button, CheckBox, RadioButton, Switch, Chip, and more for building modern, interactive React applications.
86 lines (85 loc) • 4.18 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import * as React from 'react';
import { useRef, useImperativeHandle, useState, useEffect, forwardRef, useCallback } from 'react';
import { preRender, useProviderContext, useRippleEffect, Size } from '@syncfusion/react-base';
/**
* The RadioButton component allows users to select a single option from a group, utilizing a circular input field that provides a clear user selection interface.
*
* ```typescript
* import { RadioButton } from "@syncfusion/react-buttons";
*
* <RadioButton checked={true} label="Choose this option" name="choices" />
* ```
*/
export const RadioButton = forwardRef((props, ref) => {
const { checked, defaultChecked = false, className = '', disabled = false, label = '', color, size = Size.Medium, labelPlacement = 'After', name = '', value = '', onChange, ...domProps } = props;
const isControlled = checked !== undefined;
const [isChecked, setIsChecked] = useState(() => isControlled ? !!checked : defaultChecked);
const radioInputRef = useRef(null);
const [isFocused, setIsFocused] = useState(false);
const rippleContainerRef = useRef(null);
const { dir, ripple } = useProviderContext();
const { rippleMouseDown, Ripple } = useRippleEffect(ripple, { duration: 400, isCenterRipple: true });
useEffect(() => {
if (isControlled) {
setIsChecked(!!checked);
}
}, [checked, isControlled]);
useEffect(() => {
preRender('radio');
}, []);
const publicAPI = {
checked: isChecked,
label,
labelPlacement,
value,
size,
color
};
useImperativeHandle(ref, () => ({
...publicAPI,
element: radioInputRef.current
}), [publicAPI]);
const onRadioChange = (event) => {
if (!isControlled) {
setIsChecked(event.target.checked);
}
if (onChange) {
onChange({ event, value: value });
}
};
const handleMouseDown = useCallback((e) => {
if (disabled) {
return;
}
if (ripple && rippleContainerRef.current && rippleMouseDown) {
const syntheticEvent = {
...e,
currentTarget: rippleContainerRef.current,
target: rippleContainerRef.current
};
rippleMouseDown(syntheticEvent);
}
}, [disabled, ripple, rippleMouseDown]);
const handleFocus = () => {
setIsFocused(true);
};
const handleBlur = () => {
setIsFocused(false);
};
const sizeLower = String(size).toLowerCase();
const colorLower = color ? String(color).toLowerCase() : '';
const classNames = [
'sf-radio-wrapper',
'sf-wrapper',
className,
size !== undefined && sizeLower !== 'medium' ? `sf-${sizeLower}` : '',
color && `sf-radio-${colorLower}`,
'sf-pos-relative sf-display-inline-block'
].filter(Boolean).join(' ');
const rtlClass = (dir === 'rtl') ? 'sf-rtl' : '';
const labelBefore = labelPlacement === 'Before';
const labelBottom = labelPlacement === 'Bottom';
return (_jsxs("div", { className: classNames, onMouseDown: !disabled ? handleMouseDown : undefined, children: [_jsx("input", { ref: radioInputRef, type: "radio", id: domProps.id ? domProps.id : `sf-${value}`, name: name, value: value, disabled: disabled, onChange: onRadioChange, onFocus: handleFocus, onBlur: handleBlur, className: `sf-control sf-radio ${className} sf-pos-absolute`, checked: isControlled ? !!checked : undefined, defaultChecked: !isControlled ? isChecked : undefined, ...domProps }), _jsxs("label", { className: `sf-radio-label sf-control sf-radio-${size.toLowerCase().substring(0, 2)} ${labelBefore ? 'sf-right' : ''} ${labelBottom ? 'sf-bottom' : ''} ${isFocused ? 'sf-focus' : ''} ${rtlClass}`, htmlFor: domProps.id ? domProps.id : `sf-${value}`, children: [_jsx("span", { ref: rippleContainerRef, className: "sf-ripple-container", children: ripple && !disabled && _jsx(Ripple, {}) }), _jsx("span", { className: "sf-label", children: label })] })] }));
});
export default React.memo(RadioButton);