@chayns-components/core
Version:
A set of beautiful React components for developing your own applications with chayns.
135 lines • 5.13 kB
JavaScript
import { AnimatePresence } from 'motion/react';
import React, { useCallback, useContext, useEffect, useMemo, useState } from 'react';
import { RadioButtonGroupContext } from './radio-button-group/RadioButtonGroup';
import { StyledLabelWrapper, StyledMotionRadioButtonChildren, StyledRadioButton, StyledRadioButtonCheckBox, StyledRadioButtonCheckBoxMark, StyledRadioButtonLabel, StyledRadioButtonPseudoCheckBox, StyledRadioButtonWrapper } from './RadioButton.styles';
const RadioButton = _ref => {
let {
children,
shouldShowRightElementOnlyOnChecked = false,
label,
id,
rightElement,
isDisabled = false
} = _ref;
const {
selectedRadioButtonId,
updateSelectedRadioButtonId,
radioButtonRightElements,
updateHasRightElement,
radioButtonsCanBeUnchecked
} = useContext(RadioButtonGroupContext);
const [internalIsChecked, setInternalIsChecked] = useState(false);
const [isHovered, setIsHovered] = useState(false);
const isInGroup = typeof updateSelectedRadioButtonId === 'function';
const isMarked = isInGroup ? selectedRadioButtonId === id : internalIsChecked;
const uncheckable = radioButtonsCanBeUnchecked;
const handleClick = useCallback(() => {
if (isDisabled) {
return;
}
if (uncheckable) {
if (updateSelectedRadioButtonId) {
updateSelectedRadioButtonId(id === selectedRadioButtonId ? undefined : id);
}
setInternalIsChecked(prev => !prev);
return;
}
if (typeof updateSelectedRadioButtonId === 'function') {
updateSelectedRadioButtonId(id);
}
setInternalIsChecked(true);
}, [id, isDisabled, uncheckable, selectedRadioButtonId, updateSelectedRadioButtonId]);
const handleMouseEnter = useCallback(() => {
if (!isDisabled) {
setIsHovered(true);
}
}, [isDisabled]);
const handleMouseLeave = () => {
setIsHovered(false);
};
const radioButtonRightElementMargin = useMemo(() => {
if (!radioButtonRightElements) {
return 'NONE';
}
const index = radioButtonRightElements.findIndex(element => element.id === id);
if (index < 0) {
return 'NONE';
}
const prevButton = radioButtonRightElements[index - 1];
const currentButton = radioButtonRightElements[index];
const nextButton = radioButtonRightElements[index + 1];
if (!currentButton?.hasRightElement) {
return 'NONE';
}
switch (true) {
case prevButton?.hasRightElement && !nextButton?.hasRightElement:
return 'TOP';
case !prevButton?.hasRightElement && nextButton?.hasRightElement:
return 'BOTTOM';
case currentButton?.hasRightElement && !nextButton?.hasRightElement && !prevButton?.hasRightElement:
return 'NONE';
default:
return 'BOTH';
}
}, [id, radioButtonRightElements]);
const shouldShowRightElement = useMemo(() => {
if (rightElement) {
if (shouldShowRightElementOnlyOnChecked) {
return isMarked;
}
return true;
}
return false;
}, [isMarked, rightElement, shouldShowRightElementOnlyOnChecked]);
useEffect(() => {
if (typeof updateHasRightElement === 'function') {
window.setTimeout(() => {
updateHasRightElement(id, shouldShowRightElement);
}, 10);
}
}, [id, shouldShowRightElement, updateHasRightElement]);
return useMemo(() => /*#__PURE__*/React.createElement(StyledRadioButton, {
$isDisabled: isDisabled,
$radioButtonRightElementMargin: radioButtonRightElementMargin
}, /*#__PURE__*/React.createElement(StyledRadioButtonWrapper, null, /*#__PURE__*/React.createElement(StyledRadioButtonPseudoCheckBox, {
$isDisabled: isDisabled,
$isChecked: isMarked,
onClick: handleClick
}, /*#__PURE__*/React.createElement(StyledRadioButtonCheckBoxMark, {
onMouseEnter: handleMouseEnter,
onMouseLeave: handleMouseLeave,
$isHovered: isHovered,
$isSelected: isMarked,
$isDisabled: isDisabled
})), /*#__PURE__*/React.createElement(StyledRadioButtonCheckBox, {
onClick: handleClick,
onMouseEnter: handleMouseEnter,
onMouseLeave: handleMouseLeave,
disabled: isDisabled,
$isDisabled: isDisabled,
type: "radio",
checked: isMarked,
onChange: () => {}
}), /*#__PURE__*/React.createElement(StyledLabelWrapper, null, label && /*#__PURE__*/React.createElement(StyledRadioButtonLabel, {
$isDisabled: isDisabled,
onClick: handleClick,
onMouseEnter: handleMouseEnter,
onMouseLeave: handleMouseLeave
}, label), shouldShowRightElement && rightElement)), children && /*#__PURE__*/React.createElement(AnimatePresence, {
initial: false
}, /*#__PURE__*/React.createElement(StyledMotionRadioButtonChildren, {
animate: isMarked ? {
opacity: 1,
height: 'auto'
} : {
opacity: 0,
height: 0
},
transition: {
duration: 0.2
}
}, children))), [children, handleClick, handleMouseEnter, isDisabled, isHovered, isMarked, label, radioButtonRightElementMargin, rightElement, shouldShowRightElement]);
};
RadioButton.displayName = 'RadioButton';
export default RadioButton;
//# sourceMappingURL=RadioButton.js.map