Skip to content

Commit

Permalink
refactor(Label): update props to the latest specs (Semantic-Org#474)
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffcarbs committed Sep 9, 2016
1 parent ad330a3 commit e363ffa
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 73 deletions.
45 changes: 27 additions & 18 deletions src/elements/Label/Label.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import cx from 'classnames'
import React, { PropTypes } from 'react'

import {
customPropTypes,
getElementType,
getUnhandledProps,
META,
Expand All @@ -19,8 +20,8 @@ import { Icon, Image } from '../'
*/
function Label(props) {
const {
attached, basic, children, color, corner, className, circular, detail, detailLink, floating, horizontal,
icon, image, link, onClick, onDetailClick, onRemove, pointing, removable, ribbon, size, tag, text,
attached, basic, children, color, corner, className, circular, detail, detailAs, empty, floating, horizontal,
icon, image, onClick, onDetailClick, onRemove, pointing, removable, ribbon, size, tag, content,
} = props

const handleClick = e => onClick && onClick(e, props)
Expand All @@ -31,31 +32,30 @@ function Label(props) {
size,
color,
useKeyOnly(basic, 'basic'),
useKeyOnly(circular, 'circular'),
useKeyOnly(floating, 'floating'),
useKeyOnly(horizontal, 'horizontal'),
useKeyOnly(empty, 'empty'),
useKeyOnly(tag, 'tag'),
useValueAndKey(attached, 'attached'),
useKeyOrValueAndKey(corner, 'corner'),
useKeyOrValueAndKey(pointing, 'pointing'),
useKeyOrValueAndKey(ribbon, 'ribbon'),
circular && (children && 'circular' || 'empty circular'),
// TODO how to handle image child with no image class? there are two image style labels.
(image || childrenUtils.someByType(children, Image) || childrenUtils.someByType(children, 'img')) && 'image',
'label',
className
)

const DetailComponent = (detailLink || onDetailClick) && 'a' || 'div'
const ElementType = getElementType(Label, props, () => {
if (image || link || onClick) return 'a'
})
const DetailComponent = detailAs || 'div'
const ElementType = getElementType(Label, props)
const rest = getUnhandledProps(Label, props)

return (
<ElementType className={classes} onClick={handleClick} {...rest}>
{createIcon(icon)}
{createImage(image)}
{text}
{content}
{children}
{detail && (
<DetailComponent className='detail' onClick={handleDetailClick}>{detail}</DetailComponent>
Expand Down Expand Up @@ -93,8 +93,11 @@ Label.propTypes = {
/** A label can reduce its complexity. */
basic: PropTypes.bool,

/** Primary content of the label, same as text. */
children: PropTypes.node,
/** Primary content of the label, same as content. */
children: customPropTypes.every([
customPropTypes.disallow(['icon', 'image', 'content']),
PropTypes.node,
]),

/** Classes to add to the label className. */
className: PropTypes.string,
Expand All @@ -111,16 +114,25 @@ Label.propTypes = {
/** Additional text with less emphasis. */
detail: PropTypes.string,

/** Format the detail as a link. */
detailLink: PropTypes.bool,
/** An element type to render the 'detail' as (string or function). */
detailAs: PropTypes.oneOfType([
PropTypes.string,
PropTypes.func,
]),

/** Formats the label as a dot. */
empty: customPropTypes.every([
customPropTypes.demand(['circular']),
PropTypes.bool,
]),

/** Format a label to align better alongside text. */
horizontal: PropTypes.bool,

/** Float above another element in the upper right corner. */
floating: PropTypes.bool,

/** Make the label circular, or a dot if it is empty. */
/** Make the label circular, or a dot when used with 'empty' prop. */
circular: PropTypes.bool,

/** Add an icon by icon name or pass an <Icon /> */
Expand All @@ -135,9 +147,6 @@ Label.propTypes = {
PropTypes.element,
]),

/** Format the label as a link on hover. */
link: PropTypes.bool,

/** Adds the link style when present, called with (event, props). */
onClick: PropTypes.func,

Expand Down Expand Up @@ -165,8 +174,8 @@ Label.propTypes = {
/** Format the label like a product tag. */
tag: PropTypes.bool,

/** Primary text of the label, same as children. */
text: PropTypes.node,
/** Primary content of the label, same as children. */
content: PropTypes.node,
}

export default Label
67 changes: 12 additions & 55 deletions test/specs/elements/Label/Label-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ describe('Label Component', () => {

common.propKeyOnlyToClassName(Label, 'basic')
common.propKeyOnlyToClassName(Label, 'circular')
common.propKeyOnlyToClassName(Label, 'empty')
common.propKeyOnlyToClassName(Label, 'floating')
common.propKeyOnlyToClassName(Label, 'horizontal')
common.propKeyOnlyToClassName(Label, 'tag')
Expand All @@ -33,25 +34,19 @@ describe('Label Component', () => {
.should.have.tagName('div')
})

describe('(empty) circular', () => {
it('is added to className when there are no children', () => {
shallow(<Label circular />)
.should.have.className('empty circular')
})

it('is not added to className when there are children', () => {
shallow(<Label circular>Child</Label>)
.should.not.have.className('empty circular')
})
})

describe('detail', () => {
it('renders detail as a div', () => {
shallow(<Label detail={faker.hacker.noun()} />)
.find('.detail')
.should.have.tagName('div')
})

it('renders detail using component from detailAs prop', () => {
shallow(<Label detail={faker.hacker.noun()} detailAs='a' />)
.find('.detail')
.should.have.tagName('a')
})

it('has no detail when not defined', () => {
shallow(<Label />)
.should.not.have.descendants('.detail')
Expand All @@ -72,19 +67,6 @@ describe('Label Component', () => {
})
})

describe('detailLink', () => {
it('has no detail when not defined', () => {
shallow(<Label />)
.should.not.have.descendants('.detail')
})

it('renders detail as an a tag', () => {
shallow(<Label detail={faker.hacker.noun()} detailLink />)
.find('.detail')
.should.have.tagName('a')
})
})

describe('icon', () => {
it('adds a i as first child', () => {
shallow(<Label icon={faker.hacker.noun()}><br /></Label>)
Expand Down Expand Up @@ -129,27 +111,7 @@ describe('Label Component', () => {
})
})

describe('link', () => {
it('does not render label as an "a" when not defined', () => {
shallow(<Label />)
.should.not.have.tagName('a')
})

it('renders label as an "a"', () => {
shallow(<Label link />)
.should.have.tagName('a')
})
})

describe('onClick', () => {
it('does not render as an "a" when not defined', () => {
shallow(<Label />)
.should.not.have.tagName('a')
})
it('renders label as an "a"', () => {
shallow(<Label onClick={() => null} />)
.should.have.tagName('a')
})
it('is called when label is clicked', () => {
const props = {
onClick: sandbox.spy(),
Expand Down Expand Up @@ -191,11 +153,6 @@ describe('Label Component', () => {
})

describe('onDetailClick', () => {
it('renders detail as an a tag', () => {
shallow(<Label detail={faker.hacker.noun()} onDetailClick={() => null} />)
.should.have.descendants('a.detail')
})

it('is called when detail is clicked', () => {
const props = {
detail: faker.hacker.noun(),
Expand Down Expand Up @@ -225,18 +182,18 @@ describe('Label Component', () => {
})
})

describe('text', () => {
it('has no text by default', () => {
describe('content', () => {
it('has no content by default', () => {
shallow(<Label />)
.text()
.should.be.empty()
})

it('adds the value as children', () => {
const text = faker.hacker.phrase()
shallow(<Label text={text} />)
const content = faker.hacker.phrase()
shallow(<Label content={content} />)
.children()
.should.contain.text(text)
.should.contain.text(content)
})
})
})

0 comments on commit e363ffa

Please sign in to comment.