All files / RadioButtonLabeled RadioButtonLabeled.tsx

93.75% Statements 15/16
100% Branches 0/0
50% Functions 1/2
93.75% Lines 15/16

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 129 130 131 132 133 134 135 136 137                            176x 176x                   176x   176x 176x           176x               176x                   37x   37x       37x                                                         176x   176x   176x                                                 176x                                 176x      
import _ from 'lodash';
import React from 'react';
import PropTypes from 'react-peek/prop-types';
import { lucidClassNames } from '../../util/style-helpers';
import {
	StandardProps,
	findTypes,
	omitProps,
} 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';
 
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}
				{...omitProps(
					passThroughs,
					undefined,
					_.keys(RadioButtonLabeled.propTypes),
					false
				)}
			/>
			<div {...labelChildProps} className={cx('&-label')} />
		</label>
	);
};
 
RadioButtonLabeled.displayName = 'RadioButtonLabeled';
 
RadioButtonLabeled.defaultProps = radioButtonDefaultProps;
 
RadioButtonLabeled.peek = {
	description: `
		This is 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,
 
	className: string`
		Appended to the component-specific class names set on the root element.
	`,
 
	style: object`
		Passed through to the root element.
	`,
 
	Label: any`
		Child element whose children are used to identify the purpose of this
		radio button to the user.
	`,
};
 
RadioButtonLabeled.Label = RadioButtonLabeledLabel;
 
export default RadioButtonLabeled;