Skip to content

Commit

Permalink
Support React 15.3.0 (#374)
Browse files Browse the repository at this point in the history
* fix(customPropTypes): fix don't call proptypes warning

* fix(Label): fix size PropTypes.oneOf warning

* fix(Dropdown-test): fix many warnings

* fix(Statitistic): relax child prop validation

* fix(getUnhandledProps-test): fix prop warnings

* fix(Segment): spread unhandled props only

* fix(SegmentSegments): relax propTypes and spread unhandled

* fix(Rail-test): include required position prop

* fix(commonTests): handle requiredProps in no default className test

* fix(Label): update detailLink propType

* fix(Flag-test): add required name prop

* fix(Table): spread unhandled props only

* fix(Message): spread unhandled props only

* fix(Breadcrumb): fix exclusive icon/children prop warnings

* fix(Confirm): fix spread props

* fix(StatisticValue-test): fix describe() name typo

* fix(Sidebar): remove erroneous iconClass prop

* fix(StatisticValuePropsExample): prop Label -> label
  • Loading branch information
levithomason authored Aug 5, 2016
1 parent 8b440f1 commit b2fe3bb
Show file tree
Hide file tree
Showing 20 changed files with 159 additions and 179 deletions.
1 change: 0 additions & 1 deletion docs/app/Components/Sidebar/Sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ export default class Sidebar extends Component {
className='transparent inverted icon'
icon='search'
placeholder='Search'
iconClass='search link icon'
onChange={this.handleSearchChange}
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ const StatisticValuePropsExample = () => (
<div>
<Statistic.Group>
<Statistic label='Saves' value='22' />
<Statistic Label='Signups' value={textValue} text />
<Statistic Label='Flights' value={iconValue} />
<Statistic Label='Team Members' value={imageValue} />
<Statistic label='Signups' value={textValue} text />
<Statistic label='Flights' value={iconValue} />
<Statistic label='Team Members' value={imageValue} />
</Statistic.Group>

<Statistic.Group items={items} />
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@
"node-sass": "^3.4.2",
"phantomjs-prebuilt": "^2.1.7",
"raw-loader": "^0.5.1",
"react": "^15.0.2",
"react": "^15.3.0",
"react-addons-test-utils": "^15.0.2",
"react-docgen": "^2.2.0",
"react-document-title": "^2.0.2",
Expand Down
19 changes: 9 additions & 10 deletions src/addons/Confirm/Confirm.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React, { Component, PropTypes } from 'react'
import Promise from 'bluebird'
import classNames from 'classnames'

import META from '../../utils/Meta.js'
import META from '../../utils/Meta'
import { getUnhandledProps } from '../../utils/propUtils'

import Modal from '../../modules/Modal/Modal'
import ModalContent from '../../modules/Modal/ModalContent'
import ModalFooter from '../../modules/Modal/ModalFooter'
Expand All @@ -11,7 +12,6 @@ import ModalHeader from '../../modules/Modal/ModalHeader'
export default class Confirm extends Component {
static propTypes = {
abortLabel: PropTypes.string,
className: PropTypes.string,
confirmLabel: PropTypes.string,
header: PropTypes.string,
}
Expand Down Expand Up @@ -45,20 +45,19 @@ export default class Confirm extends Component {
}

render() {
const classes = classNames(
this.props.className
)
const { header, abortLabel, confirmLabel } = this.props
const rest = getUnhandledProps(Confirm, this.props)
return (
<Modal {...this.props} className={classes} ref='modal'>
<Modal {...rest} ref='modal'>
<ModalHeader>
{this.props.header}
{header}
</ModalHeader>
<ModalContent>
{this.state.message}
</ModalContent>
<ModalFooter>
<div className='ui button' onClick={this.handleAbort}>{this.props.abortLabel}</div>
<div className='ui blue button' onClick={this.handleConfirm}>{this.props.confirmLabel}</div>
<div className='ui button' onClick={this.handleAbort}>{abortLabel}</div>
<div className='ui blue button' onClick={this.handleConfirm}>{confirmLabel}</div>
</ModalFooter>
</Modal>
)
Expand Down
19 changes: 5 additions & 14 deletions src/collections/Breadcrumb/Breadcrumb.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,30 +12,21 @@ import BreadcrumbSection from './BreadcrumbSection'
* A breadcrumb is used to show hierarchy between content.
*/
function Breadcrumb(props) {
const {
children, className, divider, icon, size, sections,
} = props
const classes = cx(
'ui',
className,
size,
'breadcrumb'
)
const { children, className, divider, icon, size, sections } = props
const rest = getUnhandledProps(Breadcrumb, props)
const classes = cx('ui', className, size, 'breadcrumb')

if (!sections) {
return <div {...rest} className={classes}>{children}</div>
}
if (!sections) return <div {...rest} className={classes}>{children}</div>

const dividerJSX = <Breadcrumb.Divider icon={icon}>{divider}</Breadcrumb.Divider>
const dividerJSX = <BreadcrumbDivider>{divider || icon}</BreadcrumbDivider>
const sectionsJSX = []

sections.forEach(({ text, ...restSection }, index) => {
const key = `${text}-${index}`
const dividerKey = `${key}-divider`

sectionsJSX.push(
<Breadcrumb.Section {...restSection} key={key}>{text}</Breadcrumb.Section>
<BreadcrumbSection {...restSection} key={key}>{text}</BreadcrumbSection>
)

if (index !== sections.length - 1) {
Expand Down
19 changes: 4 additions & 15 deletions src/collections/Breadcrumb/BreadcrumbDivider.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,13 @@ import { customPropTypes, iconPropRenderer, getUnhandledProps } from '../../util
* A divider sub-component for Breadcrumb component.
*/
function BreadcrumbDivider(props) {
const {
children, icon, className,
} = props
const classes = cx(
className,
'divider',
)
const { children, icon, className } = props
const rest = getUnhandledProps(BreadcrumbDivider, props)
const classes = cx(className, 'divider')

if (icon) {
return iconPropRenderer(icon, { ...rest, className: classes })
}
if (icon) return iconPropRenderer(icon, { ...rest, className: classes })

return <div {...rest} className={classes}>{children}</div>
return <div {...rest} className={classes}>{children || '/'}</div>
}

BreadcrumbDivider._meta = {
Expand All @@ -31,10 +24,6 @@ BreadcrumbDivider._meta = {
parent: 'Breadcrumb',
}

BreadcrumbDivider.defaultProps = {
children: '/',
}

BreadcrumbDivider.propTypes = {
/** Primary content of the Breadcrumb.Divider. */
children: customPropTypes.all([
Expand Down
7 changes: 3 additions & 4 deletions src/collections/Message/Message.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { Component, PropTypes } from 'react'
import classNames from 'classnames'
import $ from 'jquery'
import META from '../../utils/Meta'
import { getUnhandledProps } from '../../utils/propUtils'
import Header from '../../elements/Header/Header'
import Icon from '../../elements/Icon/Icon'

Expand Down Expand Up @@ -51,12 +52,10 @@ export default class Message extends Component {
</div>
)

// prevent spreading icon classes as props on message element
const messageProps = { ...this.props }
delete messageProps.icon
const rest = getUnhandledProps(Message, this.props)

return (
<div {...messageProps} className={classes} ref='message'>
<div {...rest} className={classes} ref='message'>
{this.props.dismissable && closeIcon}
{this.props.icon && icon}
{this.props.icon && content}
Expand Down
7 changes: 5 additions & 2 deletions src/collections/Table/Table.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import _ from 'lodash'
import React, { Children, Component, PropTypes } from 'react'
import cx from 'classnames'
import { customPropTypes } from '../../utils/propUtils'
import { customPropTypes, getUnhandledProps } from '../../utils/propUtils'
import META from '../../utils/Meta'
import TableColumn from './TableColumn'

Expand Down Expand Up @@ -147,8 +147,11 @@ export default class Table extends Component {
this.props.className,
'table'
)

const rest = getUnhandledProps(Table, this.props)

return (
<table {...this.props} className={classes}>
<table {...rest} className={classes}>
<thead>
<tr>
{this._getHeaders()}
Expand Down
4 changes: 2 additions & 2 deletions src/elements/Label/Label.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ Label.propTypes = {
detail: PropTypes.string,

/** Format the detail as a link. */
detailLink: PropTypes.string,
detailLink: PropTypes.bool,

/** Format a label to align better alongside text. */
horizontal: PropTypes.bool,
Expand Down Expand Up @@ -155,7 +155,7 @@ Label.propTypes = {
ribbon: PropTypes.oneOf(Label._meta.props.ribbon),

/** Size of the label. */
size: PropTypes.oneOf(Label._meta.props.sizes),
size: PropTypes.oneOf(Label._meta.props.size),

/** Format the label like a product tag. */
tag: PropTypes.bool,
Expand Down
5 changes: 4 additions & 1 deletion src/elements/Segment/Segment.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import classNames from 'classnames'
import META from '../../utils/Meta'
import Segments from './SegmentSegments'
import Header from '../Header/Header'
import { getUnhandledProps } from '../../utils/propUtils'

/**
* A segment is used to create a grouping of related content.
Expand Down Expand Up @@ -36,8 +37,10 @@ export default class Segment extends Component {
'segment'
)

const rest = getUnhandledProps(Segment, this.props)

return (
<div {...this.props} className={classes}>
<div {...rest} className={classes}>
{this.props.heading && heading}
{this.props.children}
</div>
Expand Down
17 changes: 5 additions & 12 deletions src/elements/Segment/SegmentSegments.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,14 @@
import React, { Component, PropTypes } from 'react'
import classNames from 'classnames'
import META from '../../utils/Meta'
import { customPropTypes } from '../../utils/propUtils'
import { getUnhandledProps } from '../../utils/propUtils'

/**
* A group of segments can be formatted to appear together.
*/
export default class SegmentSegments extends Component {
static propTypes = {
/**
* Must be of type Segment, Segments, H1, H2, H3, H4, H5, H6, Subheader or Message.
*/
children: customPropTypes.ofComponentTypes([
'Segment',
'SegmentSegments',
'H1', 'H2', 'H3', 'H4', 'H5', 'H6',
'Subheader',
'Message',
]),
children: PropTypes.node,
className: PropTypes.string,
}

Expand All @@ -37,8 +28,10 @@ export default class SegmentSegments extends Component {
'segments'
)

const rest = getUnhandledProps(SegmentSegments, this.props)

return (
<div {...this.props} className={classes}>
<div {...rest} className={classes}>
{children}
</div>
)
Expand Down
8 changes: 4 additions & 4 deletions src/utils/propUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export const customPropTypes = {
* @param {function[]} validators An array of propType functions.
*/
all: (validators) => {
return (props, propName, componentName) => {
return (props, propName, componentName, ...rest) => {
if (!_.isArray(validators)) {
throw new Error([
'Invalid argument supplied to all, expected an instance of array.',
Expand All @@ -88,7 +88,7 @@ export const customPropTypes = {
`all() argument "validators" should contain functions, found: ${type(validator)}.`
)
}
return validator(props, propName, componentName)
return validator(props, propName, componentName, ...rest)
}))

// we can only return one error at a time
Expand All @@ -101,7 +101,7 @@ export const customPropTypes = {
* @param {function[]} validators An array of propType functions.
*/
any: (validators) => {
return (props, propName, componentName) => {
return (props, propName, componentName, ...rest) => {
if (!_.isArray(validators)) {
throw new Error([
'Invalid argument supplied to all, expected an instance of array.',
Expand All @@ -115,7 +115,7 @@ export const customPropTypes = {
`any() argument "validators" should contain functions, found: ${type(validator)}.`
)
}
return validator(props, propName, componentName)
return validator(props, propName, componentName, ...rest)
})

// if no validator returned undefined (no error)
Expand Down
5 changes: 1 addition & 4 deletions src/views/Statistic/Statistic.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,7 @@ Statistic.propTypes = {
/** Primary content of the Statistic. */
children: customPropTypes.all([
customPropTypes.mutuallyExclusive(['label', 'value']),
customPropTypes.ofComponentTypes([
'StatisticLabel',
'StatisticValue',
]),
PropTypes.node,
]),

/** Classes that will be added to the Statistic className. */
Expand Down
4 changes: 2 additions & 2 deletions test/specs/addons/Confirm-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ describe('Confirm', () => {
common.isConformant(Confirm)

it('default prop abortLabel should be "Cancel"', () => {
shallow(<Confirm />)
.should.have.prop('abortLabel', 'Cancel')
Confirm.defaultProps.abortLabel
.should.equal('Cancel')
})
it('default prop confirmLabel should be "Yes"', () => {
Confirm.defaultProps.confirmLabel
Expand Down
5 changes: 5 additions & 0 deletions test/specs/commonTests.js
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,11 @@ const _definesPropOptions = (Component, propKey) => {
}

const _noDefaultClassNameFromProp = (Component, propKey, requiredProps = {}) => {
// required props may include a prop that creates a className
// if so, we cannot assert that it doesn't exist by default because it is required to exist
// skip assertions for required props
if (propKey in requiredProps) return

it('is not included in className when not defined', () => {
const wrapper = shallow(<Component {...requiredProps} />)
wrapper.should.not.have.className(propKey)
Expand Down
8 changes: 5 additions & 3 deletions test/specs/elements/Flag/Flag-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ import React from 'react'
import Flag from 'src/elements/Flag/Flag'
import * as common from 'test/specs/commonTests'

const requiredProps = { name: 'us' }

describe('Flag', () => {
common.isConformant(Flag)
common.propValueOnlyToClassName(Flag, 'name')
common.isConformant(Flag, requiredProps)
common.propValueOnlyToClassName(Flag, 'name', requiredProps)

it('renders an <i /> element', () => {
shallow(<Flag />)
shallow(<Flag {...requiredProps} />)
.should.have.tagName('i')
})
})
22 changes: 12 additions & 10 deletions test/specs/elements/Rail/Rail-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,21 @@ import React from 'react'
import Rail from 'src/elements/Rail/Rail'
import * as common from 'test/specs/commonTests'

const requiredProps = { position: 'left' }

describe('Rail', () => {
common.isConformant(Rail)
common.hasUIClassName(Rail)
common.propValueOnlyToClassName(Rail, 'position')
common.propKeyOnlyToClassName(Rail, 'attached')
common.propKeyOrValueToClassName(Rail, 'close')
common.propKeyOnlyToClassName(Rail, 'dividing')
common.propKeyOnlyToClassName(Rail, 'internal')
common.propValueOnlyToClassName(Rail, 'size')
common.rendersChildren(Rail)
common.isConformant(Rail, requiredProps)
common.hasUIClassName(Rail, requiredProps)
common.propValueOnlyToClassName(Rail, 'position', requiredProps)
common.propKeyOnlyToClassName(Rail, 'attached', requiredProps)
common.propKeyOrValueToClassName(Rail, 'close', requiredProps)
common.propKeyOnlyToClassName(Rail, 'dividing', requiredProps)
common.propKeyOnlyToClassName(Rail, 'internal', requiredProps)
common.propValueOnlyToClassName(Rail, 'size', requiredProps)
common.rendersChildren(Rail, requiredProps)

it('renders an div element', () => {
shallow(<Rail />)
shallow(<Rail position='left' />)
.should.have.tagName('div')
})
})
Loading

0 comments on commit b2fe3bb

Please sign in to comment.