mdc-react
Version:
Material Components for the web implemented in React
204 lines (191 loc) • 6.87 kB
JSX
import { forwardRef } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { Clone } from '../component';
import Icon from '../icon';
import { listItemCssClasses as cssClasses } from './constants';
import ListItemContent from './ListItemContent';
import ListItemEnd from './ListItemEnd';
import ListItemStart from './ListItemStart';
const ListItem = forwardRef(({
start,
content,
end,
text,
overlineText,
primaryText = text,
secondaryText,
icon,
image,
avatar,
thumbnail,
video,
leadingIcon = icon,
leadingImage = image,
leadingAvatar = avatar,
leadingThumbnail = thumbnail,
leadingVideo = video,
leadingCheckbox,
leadingRadio,
leadingSwitch,
meta,
trailingMeta = meta,
trailingIcon,
trailingCheckbox,
trailingRadio,
trailingSwitch,
activated = false,
selected = false,
disabled = false,
nonInteractive = false,
oneLine = false,
twoLines = false,
threeLines = false,
withLeadingIcon = Boolean(leadingIcon),
withLeadingImage = Boolean(leadingImage),
withLeadingAvatar = Boolean(leadingAvatar),
withLeadingThumbnail = Boolean(leadingThumbnail),
withLeadingVideo = Boolean(leadingVideo),
withLeadingCheckbox = Boolean(leadingCheckbox),
withLeadingRadio = Boolean(leadingRadio),
withLeadingSwitch = Boolean(leadingSwitch),
withTrailingMeta = Boolean(trailingMeta),
withTrailingIcon = Boolean(trailingIcon),
withTrailingCheckbox = Boolean(trailingCheckbox),
withTrailingRadio = Boolean(trailingRadio),
withTrailingSwitch = Boolean(trailingSwitch),
element = 'li',
component: Element = element,
className,
children,
...props
}, ref) => {
const lines = Boolean(overlineText) + Boolean(primaryText) + Boolean(secondaryText);
const hasStart = Boolean(
start || leadingIcon || leadingImage || leadingAvatar || leadingThumbnail ||
leadingVideo || leadingCheckbox || leadingRadio || leadingSwitch
);
const hasContent = Boolean(content || overlineText || primaryText || secondaryText);
const hasEnd = Boolean(
end || trailingMeta || trailingIcon ||
trailingCheckbox || trailingRadio || trailingSwitch
);
const classNames = classnames(cssClasses.ROOT, {
[cssClasses.ACTIVATED]: activated,
[cssClasses.SELECTED]: selected,
[cssClasses.DISABLED]: disabled,
[cssClasses.ONE_LINE]: oneLine || lines === 1,
[cssClasses.TWO_LINES]: twoLines || lines === 2,
[cssClasses.THREE_LINES]: threeLines || lines === 3,
[cssClasses.NON_INTERACTIVE]: nonInteractive,
[cssClasses.OVERLINE]: overlineText,
[cssClasses.LEADING_ICON]: withLeadingIcon,
[cssClasses.LEADING_IMAGE]: withLeadingImage,
[cssClasses.LEADING_AVATAR]: withLeadingAvatar,
[cssClasses.LEADING_THUMBNAIL]: withLeadingThumbnail,
[cssClasses.LEADING_VIDEO]: withLeadingVideo,
[cssClasses.LEADING_CHECKBOX]: withLeadingCheckbox,
[cssClasses.LEADING_RADIO]: withLeadingRadio,
[cssClasses.LEADING_SWITCH]: withLeadingSwitch,
[cssClasses.TRAILING_ICON]: withTrailingIcon,
[cssClasses.TRAILING_META]: withTrailingMeta,
[cssClasses.TRAILING_CHECKBOX]: withTrailingCheckbox,
[cssClasses.TRAILING_RADIO]: withTrailingRadio,
[cssClasses.TRAILING_SWITCH]: withTrailingSwitch
}, className);
return (
<Element ref={ref} className={classNames} {...props}>
<span className={cssClasses.RIPPLE} />
{hasStart &&
<ListItemStart>
{start}
{leadingIcon &&
<Clone
component={leadingIcon}
fallback={Icon}
/>
}
{leadingImage}
{leadingAvatar}
{leadingThumbnail}
{leadingVideo}
{leadingCheckbox}
{leadingRadio}
{leadingSwitch}
</ListItemStart>
}
{hasContent &&
<ListItemContent
overlineText={overlineText}
primaryText={primaryText}
secondaryText={secondaryText}
>
{content}
</ListItemContent>
}
{hasEnd &&
<ListItemEnd>
{end}
{trailingMeta}
{trailingIcon &&
<Clone
component={trailingIcon}
fallback={Icon}
/>
}
{trailingCheckbox}
{trailingRadio}
{trailingSwitch}
</ListItemEnd>
}
{children}
</Element>
);
});
ListItem.displayName = 'MDCListItem';
ListItem.propTypes = {
start: PropTypes.node,
content: PropTypes.node,
end: PropTypes.node,
text: PropTypes.node,
overlineText: PropTypes.node,
primaryText: PropTypes.node,
secondaryText: PropTypes.node,
icon: PropTypes.node,
image: PropTypes.element,
avatar: PropTypes.element,
thumbnail: PropTypes.element,
video: PropTypes.element,
leadingIcon: PropTypes.node,
leadingImage: PropTypes.element,
leadingAvatar: PropTypes.element,
leadingThumbnail: PropTypes.element,
leadingVideo: PropTypes.element,
leadingCheckbox: PropTypes.element,
leadingRadio: PropTypes.element,
leadingSwitch: PropTypes.element,
meta: PropTypes.node,
trailingMeta: PropTypes.node,
trailingIcon: PropTypes.node,
trailingCheckbox: PropTypes.element,
trailingRadio: PropTypes.element,
trailingSwitch: PropTypes.element,
activated: PropTypes.bool,
selected: PropTypes.bool,
disabled: PropTypes.bool,
nonInteractive: PropTypes.bool,
withLeadingIcon: PropTypes.bool,
withLeadingImage: PropTypes.bool,
withLeadingAvatar: PropTypes.bool,
withLeadingThumbnail: PropTypes.bool,
withLeadingVideo: PropTypes.bool,
withLeadingCheckbox: PropTypes.bool,
withLeadingRadio: PropTypes.bool,
withLeadingSwitch: PropTypes.bool,
withTrailingMeta: PropTypes.bool,
withTrailingIcon: PropTypes.bool,
withTrailingCheckbox: PropTypes.bool,
withTrailingRadio: PropTypes.bool,
withTrailingSwitch: PropTypes.bool
};
export default ListItem;