All files / RadioButtonLabeled RadioButtonLabeled.tsx

94.11% Statements 16/17
100% Branches 0/0
50% Functions 1/2
94.11% Lines 16/17

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128                      5x 5x                   5x   5x 5x     5x     5x             5x                   80x   80x       80x                                               5x   5x   5x                                           5x                                       5x      
import _ from 'lodash';
import React from 'react';
import PropTypes from 'prop-types';
 
import { lucidClassNames } from '../../util/style-helpers';
import { StandardProps, findTypes } from '../../util/component-types';
import RadioButton, {
	IRadioButtonProps,
	defaultProps as radioButtonDefaultProps,
} from '../RadioButton/RadioButton';
 
const cx = lucidClassNames.bind('&-RadioButtonLabeled');
const { any, object, string } = PropTypes;
 
export interface IRadioButtonLabeledLabelProps
	extends StandardProps,
		React.DetailedHTMLProps<
			React.HTMLAttributes<HTMLDivElement>,
			HTMLDivElement
		> {
	description?: string;
}
const RadioButtonLabeledLabel = (_props: IRadioButtonLabeledLabelProps): null =>
	null;
RadioButtonLabeledLabel.displayName = 'RadioButtonLabeled.Label';
RadioButtonLabeledLabel.peek = {
	description: `Used to identify the purpose of this radio button to the user -- can be any renderable content.`,
};
RadioButtonLabeledLabel.propName = 'Label';
 
/** TODO: Remove nonPassThroughs when the component is converted to a functional component */
const nonPassThroughs = ['className', 'style', 'Label'];
export interface IRadioButtonLabeledProps extends IRadioButtonProps {
	/** Child element whose children are used to identify the purpose of this
		radio button to the user. */
	Label?: string | (React.ReactNode & { props: IRadioButtonLabeledLabelProps });
}
 
export const RadioButtonLabeled = (
	props: IRadioButtonLabeledProps
): React.ReactElement => {
	const {
		className,
		isDisabled,
		isSelected,
		onSelect,
		style,
		...passThroughs
	} = props;
 
	const labelChildProps = _.first(
		_.map(findTypes(props, RadioButtonLabeled.Label), 'props')
	);
 
	return (
		<label
			className={cx(
				'&',
				{
					'&-is-disabled': isDisabled,
					'&-is-selected': isSelected,
				},
				className
			)}
			style={style}
		>
			<RadioButton
				className={className}
				isDisabled={isDisabled}
				isSelected={isSelected}
				onSelect={onSelect}
				{..._.omit(passThroughs as any, nonPassThroughs)}
			/>
			<div {...labelChildProps} className={cx('&-label')} />
		</label>
	);
};
 
RadioButtonLabeled.displayName = 'RadioButtonLabeled';
 
RadioButtonLabeled.defaultProps = radioButtonDefaultProps;
 
RadioButtonLabeled.peek = {
	description: `A composite of the \`RadioButton\` component and the native \`label\` element.`,
	notes: {
		overview: `
			A round two-state toggle with a label that explains the action or selection. This is a composite of \`RadioButton\` and the native
			\`label\` element.		`,
		intendedUse: `
			- Use radio button to allow users to select one item. Commonly used to select filters or settings. For interactions where users can select mutiple options, use \`CheckboxLabeled\`. 
			- Use radio buttons for 2-3 options where you want to expose all options.
			- Use \`SingleSelect\` for 3-10 options where it is not a priority to expose all options.
			- Use \`RadioButtonLabeled\` for vertical lists of options. Use \`RadioGroup\` for horizontal lists of options.
		`,
		technicalRecommendations: `
			- Use the styles on the parent container of \`RadioButtonLabeled\` to ensure only the radio buttons and their labels are clickable.
			- Any props that are not explicitly defined in \`propTypes\` are passed to the native radio button control.
			`,
	},
	categories: ['controls', 'toggles'],
	extend: 'RadioButton',
	madeFrom: ['RadioButton'],
};
 
RadioButtonLabeled.propTypes = {
	...RadioButton.propTypes,
 
	/**
		Appended to the component-specific class names set on the root element.
	*/
	className: string,
 
	/**
		Passed through to the root element.
	*/
	style: object,
 
	/**
		Child element whose children are used to identify the purpose of this
		radio button to the user.
	*/
	Label: any,
};
 
RadioButtonLabeled.Label = RadioButtonLabeledLabel;
 
export default RadioButtonLabeled;