terra-clinical-label-value-view
Version:
The label value view component displays a label and the associated value or list of values underneath the label.
92 lines (83 loc) • 2.58 kB
JSX
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import classNamesBind from 'classnames/bind';
import ThemeContext from 'terra-theme-context';
import styles from './LabelValueView.module.scss';
const cx = classNamesBind.bind(styles);
const propTypes = {
/**
* The label of the LabelValueView.
*/
label: PropTypes.string.isRequired,
/**
* The text to be displayed underneath the label with the provided styling.
*/
textValue: PropTypes.string,
/**
* Indicates if the LabelValueView is created inside a description list or not.
* If it is not valued, it will take false as a default, meaning that is is not a child of a description list.
*/
isChildOfDescriptionList: PropTypes.bool,
/**
* The id of the element to be used as the accessible label for LabelValueView.
*/
ariaLabelledBy: PropTypes.string,
/**
* Child component(s) to display underneath the label.
*/
children: PropTypes.node,
};
const defaultProps = {
textValue: '',
children: undefined,
isChildOfDescriptionList: false,
ariaLabelledBy: undefined,
};
const LabelValueView = ({
label, textValue, isChildOfDescriptionList, ariaLabelledBy, children, ...customProps
}) => {
let textValueSection;
const theme = React.useContext(ThemeContext);
const labelValueViewClass = classNames(
cx(
'label-value-view',
theme.className,
),
customProps.className,
);
if (!textValue && !children) {
textValueSection = <div className={cx('value')}>--</div>;
} else if (textValue) {
textValueSection = <div className={cx('value')}>{textValue}</div>;
}
const termDefinition = (
<React.Fragment>
<dt className={cx('label')}>{label}</dt>
<dd className={cx('value-wrapper')}>
{textValueSection}
{children}
</dd>
</React.Fragment>
);
/**
* If LabelValueView is a child of a description list (<dl>), then just the term and definition are returned.
* Otherwise, a description list encapsulating the term and definition is returned.
* The reason for this is that <dt> and <dd> tags must always be children of a <dl> to be valid html.
*/
if (isChildOfDescriptionList) {
return (
<React.Fragment>
{termDefinition}
</React.Fragment>
);
}
return (
<dl {...customProps} className={labelValueViewClass} aria-labelledby={ariaLabelledBy}>
{termDefinition}
</dl>
);
};
LabelValueView.propTypes = propTypes;
LabelValueView.defaultProps = defaultProps;
export default LabelValueView;