UNPKG

@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
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);