Skip to content

Commit

Permalink
feat(List): handler for <List selection/> (#1530)
Browse files Browse the repository at this point in the history
feat(List): handler for <List selection/>
  • Loading branch information
josie11 authored and levithomason committed Apr 3, 2017
1 parent 754416e commit bf09457
Show file tree
Hide file tree
Showing 10 changed files with 328 additions and 228 deletions.
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
220 changes: 120 additions & 100 deletions src/elements/List/List.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import cx from 'classnames'
import _ from 'lodash'
import React, { PropTypes } from 'react'
import React, { Component, PropTypes } from 'react'

import {
customPropTypes,
Expand All @@ -23,124 +23,144 @@ import ListList from './ListList'
/**
* A list groups related content.
*/
function List(props) {
const {
animated,
bulleted,
celled,
children,
className,
divided,
floated,
horizontal,
inverted,
items,
link,
ordered,
relaxed,
selection,
size,
verticalAlign,
} = props

const classes = cx(
'ui',
size,
useKeyOnly(animated, 'animated'),
useKeyOnly(bulleted, 'bulleted'),
useKeyOnly(celled, 'celled'),
useKeyOnly(divided, 'divided'),
useKeyOnly(horizontal, 'horizontal'),
useKeyOnly(inverted, 'inverted'),
useKeyOnly(link, 'link'),
useKeyOnly(ordered, 'ordered'),
useKeyOnly(selection, 'selection'),
useKeyOrValueAndKey(relaxed, 'relaxed'),
useValueAndKey(floated, 'floated'),
useVerticalAlignProp(verticalAlign),
'list',
className,
)
const rest = getUnhandledProps(List, props)
const ElementType = getElementType(List, props)

if (!_.isNil(children)) {
return <ElementType {...rest} role='list' className={classes}>{children}</ElementType>
}
class List extends Component {
static propTypes = {
/** An element type to render as (string or function). */
as: customPropTypes.as,

return (
<ElementType {...rest} role='list' className={classes}>
{_.map(items, (item) => ListItem.create(item))}
</ElementType>
)
}
/** A list can animate to set the current item apart from the list. */
animated: PropTypes.bool,

List._meta = {
name: 'List',
type: META.TYPES.ELEMENT,
}
/** A list can mark items with a bullet. */
bulleted: PropTypes.bool,

List.propTypes = {
/** An element type to render as (string or function). */
as: customPropTypes.as,
/** A list can divide its items into cells. */
celled: PropTypes.bool,

/** A list can animate to set the current item apart from the list. */
animated: PropTypes.bool,
/** Primary content. */
children: PropTypes.node,

/** A list can mark items with a bullet. */
bulleted: PropTypes.bool,
/** Additional classes. */
className: PropTypes.string,

/** A list can divide its items into cells. */
celled: PropTypes.bool,
/** A list can show divisions between content. */
divided: PropTypes.bool,

/** Primary content. */
children: PropTypes.node,
/** An list can be floated left or right. */
floated: PropTypes.oneOf(SUI.FLOATS),

/** Additional classes. */
className: PropTypes.string,
/** A list can be formatted to have items appear horizontally. */
horizontal: PropTypes.bool,

/** A list can show divisions between content. */
divided: PropTypes.bool,
/** A list can be inverted to appear on a dark background. */
inverted: PropTypes.bool,

/** An list can be floated left or right. */
floated: PropTypes.oneOf(SUI.FLOATS),
/** Shorthand array of props for ListItem. */
items: customPropTypes.collectionShorthand,

/** A list can be formatted to have items appear horizontally. */
horizontal: PropTypes.bool,
/** A list can be specially formatted for navigation links. */
link: PropTypes.bool,

/** A list can be inverted to appear on a dark background. */
inverted: 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,
]),

/** Shorthand array of props for ListItem. */
items: customPropTypes.collectionShorthand,
/** A list can be ordered numerically. */
ordered: PropTypes.bool,

/** A list can be specially formatted for navigation links. */
link: PropTypes.bool,
/** A list can relax its padding to provide more negative space. */
relaxed: PropTypes.oneOfType([
PropTypes.bool,
PropTypes.oneOf(['very']),
]),

/** A list can be ordered numerically. */
ordered: PropTypes.bool,
/** A selection list formats list items as possible choices. */
selection: PropTypes.bool,

/** A list can relax its padding to provide more negative space. */
relaxed: PropTypes.oneOfType([
PropTypes.bool,
PropTypes.oneOf(['very']),
]),
/** A list can vary in size. */
size: PropTypes.oneOf(SUI.SIZES),

/** A selection list formats list items as possible choices. */
selection: PropTypes.bool,
/** An element inside a list can be vertically aligned. */
verticalAlign: PropTypes.oneOf(SUI.VERTICAL_ALIGNMENTS),
}

/** A list can vary in size. */
size: PropTypes.oneOf(SUI.SIZES),
static _meta = {
name: 'List',
type: META.TYPES.ELEMENT,
}

/** An element inside a list can be vertically aligned. */
verticalAlign: PropTypes.oneOf(SUI.VERTICAL_ALIGNMENTS),
static Content = ListContent
static Description = ListDescription
static Header = ListHeader
static Icon = ListIcon
static Item = ListItem
static List = ListList

handleItemOverrides = predefinedProps => ({
onClick: (e, itemProps) => {
_.invoke(predefinedProps, 'onClick', e, itemProps)
_.invoke(this.props, 'onItemClick', e, itemProps)
},
})

render() {
const {
animated,
bulleted,
celled,
children,
className,
divided,
floated,
horizontal,
inverted,
items,
link,
ordered,
relaxed,
selection,
size,
verticalAlign,
} = this.props

const classes = cx(
'ui',
size,
useKeyOnly(animated, 'animated'),
useKeyOnly(bulleted, 'bulleted'),
useKeyOnly(celled, 'celled'),
useKeyOnly(divided, 'divided'),
useKeyOnly(horizontal, 'horizontal'),
useKeyOnly(inverted, 'inverted'),
useKeyOnly(link, 'link'),
useKeyOnly(ordered, 'ordered'),
useKeyOnly(selection, 'selection'),
useKeyOrValueAndKey(relaxed, 'relaxed'),
useValueAndKey(floated, 'floated'),
useVerticalAlignProp(verticalAlign),
'list',
className,
)
const rest = getUnhandledProps(List, this.props)
const ElementType = getElementType(List, this.props)

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

return (
<ElementType {...rest} role='list' className={classes}>
{_.map(items, item => ListItem.create(item, { overrideProps: this.handleItemOverrides }))}
</ElementType>
)
}
}

List.Content = ListContent
List.Description = ListDescription
List.Header = ListHeader
List.Icon = ListIcon
List.Item = ListItem
List.List = ListList

export default List
4 changes: 1 addition & 3 deletions src/elements/List/ListContent.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,7 @@ function ListContent(props) {
const rest = getUnhandledProps(ListContent, props)
const ElementType = getElementType(ListContent, props)

if (!_.isNil(children)) {
return <ElementType {...rest} className={classes}>{children}</ElementType>
}
if (!_.isNil(children)) return <ElementType {...rest} className={classes}>{children}</ElementType>

return (
<ElementType {...rest} className={classes}>
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
Loading

0 comments on commit bf09457

Please sign in to comment.