nexxtway/react-rainbow

View on GitHub
src/components/ButtonOption/index.js

Summary

Maintainability
A
2 hrs
Test Coverage
import React, { useContext } from 'react';
import PropTypes from 'prop-types';
import RenderIf from '../RenderIf';
import { ButtonGroupPickerContext } from '../ButtonGroupPicker/context';
import HiddenElement from '../Structural/hiddenElement';
import { StyledLabel, StyledText, StyledDivider } from './styled';
import isOptionSelected from './helpers/isOptionSelected';
import { useUniqueIdentifier } from '../../libs/hooks';

/**
 * @category Form
 */
export default function ButtonOption(props) {
    const inputId = useUniqueIdentifier('button-option');
    const { className, style, name, label, disabled, onClick } = props;

    const {
        type,
        values,
        name: contextName,
        onChange,
        ariaDescribedBy,
        size,
        variant,
    } = useContext(ButtonGroupPickerContext);
    const checked = isOptionSelected(values, name);
    const handleClick = () => onClick({ isSelected: checked });
    const isShaded = variant === 'shaded';

    return (
        <StyledLabel
            className={className}
            style={style}
            onClick={handleClick}
            checked={checked}
            htmlFor={inputId}
            variant={variant}
        >
            <HiddenElement
                id={inputId}
                as="input"
                type={type}
                name={contextName}
                value={name}
                aria-describedby={ariaDescribedBy}
                checked={checked}
                onChange={onChange}
                disabled={disabled}
            />
            <StyledText size={size} disabled={disabled} checked={checked} variant={variant}>
                {label}
            </StyledText>
            <RenderIf isTrue={isShaded}>
                <StyledDivider />
            </RenderIf>
        </StyledLabel>
    );
}

ButtonOption.propTypes = {
    /** A CSS class for the outer element, in addition to the component's base classes. */
    className: PropTypes.string,
    /** An object with a custom style applied to the outer element. */
    style: PropTypes.object,
    /** It is a unique value that identifies the picker option. */
    name: PropTypes.string,
    /** The content to be displayed inside the ButtonOption */
    label: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
    /** Specifies whether this button should be displayed in a disabled state. Disabled buttons can't be clicked. */
    disabled: PropTypes.bool,
    /** The action triggered when the element is clicked. */
    onClick: PropTypes.func,
};

ButtonOption.defaultProps = {
    className: undefined,
    style: undefined,
    name: undefined,
    label: undefined,
    disabled: false,
    onClick: () => {},
};