Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(List): handler for <List selection/> #1530

Merged
merged 10 commits into from
Apr 3, 2017
10 changes: 9 additions & 1 deletion src/elements/List/List.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { default as ListContent } from './ListContent';
import { default as ListDescription } from './ListDescription';
import { default as ListHeader } from './ListHeader';
import { default as ListIcon } from './ListIcon';
import { default as ListItem } from './ListItem';
import { default as ListItem, ListItemProps } from './ListItem';
import { default as ListList } from './ListList';

export interface ListProps {
Expand Down Expand Up @@ -51,6 +51,14 @@ export interface ListProps {
/** A list can be specially formatted for navigation links. */
link?: boolean;

/**
* onClick handler for ListItem. Mutually exclusive with children.
*
* @param {SyntheticEvent} event - React's original SyntheticEvent.
* @param {object} data - All item props.
*/
onItemClick?: (event: React.MouseEvent<HTMLAnchorElement>, data: ListItemProps) => void;

/** A list can be ordered numerically. */
ordered?: boolean;

Expand Down
14 changes: 13 additions & 1 deletion src/elements/List/List.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ function List(props) {
inverted,
items,
link,
onItemClick,
ordered,
relaxed,
selection,
Expand Down Expand Up @@ -70,7 +71,7 @@ function List(props) {

return (
<ElementType {...rest} role='list' className={classes}>
{_.map(items, (item) => ListItem.create(item))}
{_.map(items, (item) => ListItem.create(item, { onClick: onItemClick }))}
</ElementType>
)
}
Expand Down Expand Up @@ -117,6 +118,17 @@ List.propTypes = {
/** A list can be specially formatted for navigation links. */
link: PropTypes.bool,

/**
* onClick handler for ListItem. Mutually exclusive with children.
*
* @param {SyntheticEvent} event - React's original SyntheticEvent.
* @param {object} data - All item props.
*/
onItemClick: customPropTypes.every([
customPropTypes.disallow(['children']),
PropTypes.func,
]),

/** A list can be ordered numerically. */
ordered: PropTypes.bool,

Expand Down
8 changes: 8 additions & 0 deletions src/elements/List/ListItem.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ export interface ListItemProps {
/** Shorthand for Image. */
image?: any;

/**
* Called on click.
*
* @param {SyntheticEvent} event - React's original SyntheticEvent.
* @param {object} data - All props.
*/
onClick?: (event: React.MouseEvent<HTMLAnchorElement>, data: ListItemProps) => void;

/** A value for an ordered list. */
value?: string;
}
Expand Down
23 changes: 18 additions & 5 deletions src/elements/List/ListItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,28 @@ function ListItem(props) {
const rest = getUnhandledProps(ListItem, props)
const valueProp = ElementType === 'li' ? { value } : { 'data-value': value }

const handleClick = (e) => {
const { onClick } = props

if (onClick) onClick(e, props)
}

if (!_.isNil(children)) {
return <ElementType {...rest} {...valueProp} role='listitem' className={classes}>{children}</ElementType>
return (
<ElementType {...rest} {...valueProp} role='listitem' className={classes} onClick={handleClick}>
{children}
</ElementType>
)
}

const iconElement = ListIcon.create(icon)
const imageElement = Image.create(image)


// See description of `content` prop for explanation about why this is necessary.
if (!isValidElement(content) && _.isPlainObject(content)) {
return (
<ElementType {...rest} {...valueProp} role='listitem' className={classes}>
<ElementType {...rest} {...valueProp} role='listitem' className={classes} onClick={handleClick}>
{iconElement || imageElement}
{ListContent.create(content, { header, description })}
</ElementType>
Expand All @@ -63,10 +74,9 @@ function ListItem(props) {

const headerElement = ListHeader.create(header)
const descriptionElement = ListDescription.create(description)

if (iconElement || imageElement) {
return (
<ElementType {...rest} {...valueProp} role='listitem' className={classes}>
<ElementType {...rest} {...valueProp} role='listitem' className={classes} onClick={handleClick}>
{iconElement || imageElement}
{(content || headerElement || descriptionElement) && (
<ListContent>
Expand All @@ -80,7 +90,7 @@ function ListItem(props) {
}

return (
<ElementType {...rest} {...valueProp} role='listitem' className={classes}>
<ElementType {...rest} {...valueProp} role='listitem' className={classes} onClick={handleClick}>
{headerElement}
{descriptionElement}
{content}
Expand Down Expand Up @@ -145,6 +155,9 @@ ListItem.propTypes = {
customPropTypes.itemShorthand,
]),

/** A ListItem can be clicked */
onClick: PropTypes.func,

/** A value for an ordered list. */
value: PropTypes.string,
}
Expand Down