diff --git a/src/views/Card/Card.js b/src/views/Card/Card.js index e7cd9f321e..9621e8dd95 100644 --- a/src/views/Card/Card.js +++ b/src/views/Card/Card.js @@ -11,23 +11,14 @@ import { useKeyOnly, } from '../../lib' import Image from '../../elements/Image' - import CardContent from './CardContent' import CardDescription from './CardDescription' import CardGroup from './CardGroup' import CardHeader from './CardHeader' import CardMeta from './CardMeta' -const _meta = { - name: 'Card', - type: META.TYPES.VIEW, - props: { - color: SUI.COLORS, - }, -} - /** - * A card displays site content in a manner similar to a playing card + * A card displays site content in a manner similar to a playing card. */ export default class Card extends Component { static propTypes = { @@ -44,7 +35,7 @@ export default class Card extends Component { className: PropTypes.string, /** A Card can be formatted to display different colors. */ - color: PropTypes.oneOf(_meta.props.color), + color: PropTypes.oneOf(SUI.COLORS), /** Shorthand for CardDescription. */ description: customPropTypes.itemShorthand, @@ -80,7 +71,10 @@ export default class Card extends Component { raised: PropTypes.bool, } - static _meta = _meta + static _meta = { + name: 'Card', + type: META.TYPES.VIEW, + } static Content = CardContent static Description = CardDescription diff --git a/src/views/Card/CardContent.js b/src/views/Card/CardContent.js index e42a5e935b..743532ccdf 100644 --- a/src/views/Card/CardContent.js +++ b/src/views/Card/CardContent.js @@ -1,5 +1,5 @@ -import _ from 'lodash' import cx from 'classnames' +import _ from 'lodash' import React, { PropTypes } from 'react' import { @@ -15,10 +15,18 @@ import CardHeader from './CardHeader' import CardMeta from './CardMeta' /** - * A card can contain blocks of content or extra content meant to be formatted separately from the main content + * A card can contain blocks of content or extra content meant to be formatted separately from the main content. */ function CardContent(props) { - const { children, className, description, extra, header, meta } = props + const { + children, + className, + description, + extra, + header, + meta, + } = props + const classes = cx( className, useKeyOnly(extra, 'extra'), @@ -59,7 +67,7 @@ CardContent.propTypes = { /** Shorthand for CardDescription. */ description: customPropTypes.itemShorthand, - /** A card can contain extra content meant to be formatted separately from the main content */ + /** A card can contain extra content meant to be formatted separately from the main content. */ extra: PropTypes.bool, /** Shorthand for CardHeader. */ diff --git a/src/views/Card/CardDescription.js b/src/views/Card/CardDescription.js index a51cfc235e..0a0a95780f 100644 --- a/src/views/Card/CardDescription.js +++ b/src/views/Card/CardDescription.js @@ -1,5 +1,5 @@ -import _ from 'lodash' import cx from 'classnames' +import _ from 'lodash' import React, { PropTypes } from 'react' import { @@ -10,7 +10,7 @@ import { } from '../../lib' /** - * A card can contain a description with one or more paragraphs + * A card can contain a description with one or more paragraphs. */ function CardDescription(props) { const { children, className, content } = props @@ -18,7 +18,11 @@ function CardDescription(props) { const rest = getUnhandledProps(CardDescription, props) const ElementType = getElementType(CardDescription, props) - return {_.isNil(children) ? content : children} + return ( + + {_.isNil(children) ? content : children} + + ) } CardDescription._meta = { diff --git a/src/views/Card/CardGroup.js b/src/views/Card/CardGroup.js index 414144f062..d79b729ab1 100644 --- a/src/views/Card/CardGroup.js +++ b/src/views/Card/CardGroup.js @@ -1,5 +1,5 @@ -import _ from 'lodash' import cx from 'classnames' +import _ from 'lodash' import React, { PropTypes } from 'react' import { @@ -17,11 +17,19 @@ import Card from './Card' * A group of cards. */ function CardGroup(props) { - const { children, className, doubling, items, itemsPerRow, stackable } = props + const { + children, + className, + doubling, + items, + itemsPerRow, + stackable, + } = props + const classes = cx('ui', - useWidthProp(itemsPerRow), useKeyOnly(doubling, 'doubling'), useKeyOnly(stackable, 'stackable'), + useWidthProp(itemsPerRow), className, 'cards', ) @@ -43,9 +51,6 @@ function CardGroup(props) { CardGroup._meta = { name: 'CardGroup', parent: 'Card', - props: { - itemsPerRow: SUI.WIDTHS, - }, type: META.TYPES.VIEW, } @@ -59,16 +64,16 @@ CardGroup.propTypes = { /** Additional classes. */ className: PropTypes.string, - /** A group of cards can double its column width for mobile */ + /** A group of cards can double its column width for mobile. */ doubling: PropTypes.bool, /** Shorthand array of props for Card. */ items: customPropTypes.collectionShorthand, - /** A group of cards can set how many cards should exist in a row */ - itemsPerRow: PropTypes.oneOf(CardGroup._meta.props.itemsPerRow), + /** A group of cards can set how many cards should exist in a row. */ + itemsPerRow: PropTypes.oneOf(SUI.WIDTHS), - /** A group of cards can automatically stack rows to a single columns on mobile devices */ + /** A group of cards can automatically stack rows to a single columns on mobile devices. */ stackable: PropTypes.bool, } diff --git a/src/views/Card/CardHeader.js b/src/views/Card/CardHeader.js index 2b2312f3bf..278861de85 100644 --- a/src/views/Card/CardHeader.js +++ b/src/views/Card/CardHeader.js @@ -1,5 +1,5 @@ -import _ from 'lodash' import cx from 'classnames' +import _ from 'lodash' import React, { PropTypes } from 'react' import { @@ -10,7 +10,7 @@ import { } from '../../lib' /** - * A card can contain a header + * A card can contain a header. */ function CardHeader(props) { const { children, className, content } = props @@ -18,7 +18,11 @@ function CardHeader(props) { const rest = getUnhandledProps(CardHeader, props) const ElementType = getElementType(CardHeader, props) - return {_.isNil(children) ? content : children} + return ( + + {_.isNil(children) ? content : children} + + ) } CardHeader._meta = { diff --git a/src/views/Card/CardMeta.js b/src/views/Card/CardMeta.js index da17faa6a6..385a275304 100644 --- a/src/views/Card/CardMeta.js +++ b/src/views/Card/CardMeta.js @@ -1,5 +1,5 @@ -import _ from 'lodash' import cx from 'classnames' +import _ from 'lodash' import React, { PropTypes } from 'react' import { @@ -10,7 +10,7 @@ import { } from '../../lib' /** - * A card can contain content metadata + * A card can contain content metadata. */ function CardMeta(props) { const { children, className, content } = props @@ -18,7 +18,11 @@ function CardMeta(props) { const rest = getUnhandledProps(CardMeta, props) const ElementType = getElementType(CardMeta, props) - return {_.isNil(children) ? content : children} + return ( + + {_.isNil(children) ? content : children} + + ) } CardMeta._meta = { diff --git a/src/views/Card/index.d.ts b/src/views/Card/index.d.ts index 3e6435cb82..01919d6426 100644 --- a/src/views/Card/index.d.ts +++ b/src/views/Card/index.d.ts @@ -1,7 +1,8 @@ -import { ReactMouseEvents, SemanticCOLORS, SemanticWIDTHS } from '../..'; import * as React from 'react'; +import { SemanticCOLORS, SemanticWIDTHS } from '../..'; -interface CardProps extends ReactMouseEvents { +interface CardProps { + [key: string]: any; /** An element type to render as (string or function). */ as?: any; @@ -46,13 +47,13 @@ interface CardProps extends ReactMouseEvents { * @param {SyntheticEvent} event - React's original SyntheticEvent. * @param {object} data - All props. */ - onClick?: React.MouseEventHandler; + onClick?: (event: React.MouseEvent, data: CardProps) => void; /** A Card can be formatted to raise above the page. */ raised?: boolean; } -interface CardClass extends React.ComponentClass { +interface CardComponent extends React.ComponentClass { Content: typeof CardContent; Description: typeof CardDescription; Group: typeof CardGroup; @@ -60,9 +61,11 @@ interface CardClass extends React.ComponentClass { Meta: typeof CardMeta; } -export const Card: CardClass; +export const Card: CardComponent; interface CardContentProps { + [key: string]: any; + /** An element type to render as (string or function). */ as?: any; @@ -75,7 +78,7 @@ interface CardContentProps { /** Shorthand for CardDescription. */ description?: string; - /** A card can contain extra content meant to be formatted separately from the main content */ + /** A card can contain extra content meant to be formatted separately from the main content. */ extra?: boolean; /** Shorthand for CardHeader. */ @@ -85,9 +88,11 @@ interface CardContentProps { meta?: any; } -export const CardContent: React.ComponentClass; +export const CardContent: React.StatelessComponent; interface CardDescriptionProps { + [key: string]: any; + /** An element type to render as (string or function). */ as?: any; @@ -98,12 +103,14 @@ interface CardDescriptionProps { className?: string; /** Shorthand for primary content. */ - content?: any; + content?: React.ReactNode; } -export const CardDescription: React.ComponentClass; +export const CardDescription: React.StatelessComponent; interface CardGroupProps { + [key: string]: any; + /** An element type to render as (string or function). */ as?: any; @@ -113,22 +120,24 @@ interface CardGroupProps { /** Additional classes. */ className?: string; - /** A group of cards can double its column width for mobile */ + /** A group of cards can double its column width for mobile. */ doubling?: boolean; /** Shorthand array of props for Card. */ items?: Array; - /** A group of cards can set how many cards should exist in a row */ + /** A group of cards can set how many cards should exist in a row. */ itemsPerRow?: SemanticWIDTHS; - /** A group of cards can automatically stack rows to a single columns on mobile devices */ + /** A group of cards can automatically stack rows to a single columns on mobile devices. */ stackable?: boolean; } -export const CardGroup: React.ComponentClass; +export const CardGroup: React.StatelessComponent; interface CardHeaderProps { + [key: string]: any; + /** An element type to render as (string or function). */ as?: any; @@ -139,12 +148,14 @@ interface CardHeaderProps { className?: string; /** Shorthand for primary content. */ - content?: any; + content?: React.ReactNode; } -export const CardHeader: React.ComponentClass; +export const CardHeader: React.StatelessComponent; interface CardMetaProps { + [key: string]: any; + /** An element type to render as (string or function). */ as?: any; @@ -155,7 +166,7 @@ interface CardMetaProps { className?: string; /** Shorthand for primary content. */ - content?: any; + content?: React.ReactNode; } -export const CardMeta: React.ComponentClass; +export const CardMeta: React.StatelessComponent; diff --git a/test/specs/views/Card/Card-test.js b/test/specs/views/Card/Card-test.js index 2c33539a37..fa3037afb9 100644 --- a/test/specs/views/Card/Card-test.js +++ b/test/specs/views/Card/Card-test.js @@ -1,23 +1,27 @@ import faker from 'faker' import React from 'react' -import * as common from 'test/specs/commonTests' -import { sandbox } from 'test/utils' +import { SUI } from 'src/lib' import Card from 'src/views/Card/Card' import CardContent from 'src/views/Card/CardContent' import CardDescription from 'src/views/Card/CardDescription' import CardGroup from 'src/views/Card/CardGroup' import CardHeader from 'src/views/Card/CardHeader' import CardMeta from 'src/views/Card/CardMeta' +import * as common from 'test/specs/commonTests' +import { sandbox } from 'test/utils' describe('Card', () => { common.isConformant(Card) - common.hasUIClassName(Card) common.hasSubComponents(Card, [CardContent, CardDescription, CardGroup, CardHeader, CardMeta]) + common.hasUIClassName(Card) + common.rendersChildren(Card) + common.propKeyOnlyToClassName(Card, 'centered') common.propKeyOnlyToClassName(Card, 'fluid') common.propKeyOnlyToClassName(Card, 'raised') - common.rendersChildren(Card) + + common.propValueOnlyToClassName(Card, 'color', SUI.COLORS) it('renders a
by default', () => { shallow().should.have.tagName('div') diff --git a/test/specs/views/Card/CardContent-test.js b/test/specs/views/Card/CardContent-test.js index 40850438ea..e7bcd3575c 100644 --- a/test/specs/views/Card/CardContent-test.js +++ b/test/specs/views/Card/CardContent-test.js @@ -1,11 +1,12 @@ -import * as common from 'test/specs/commonTests' import CardContent from 'src/views/Card/CardContent' import CardDescription from 'src/views/Card/CardDescription' import CardHeader from 'src/views/Card/CardHeader' import CardMeta from 'src/views/Card/CardMeta' +import * as common from 'test/specs/commonTests' describe('CardContent', () => { common.isConformant(CardContent) + common.rendersChildren(CardContent) common.implementsShorthandProp(CardContent, { propKey: 'header', @@ -24,5 +25,4 @@ describe('CardContent', () => { }) common.propKeyOnlyToClassName(CardContent, 'extra') - common.rendersChildren(CardContent) }) diff --git a/test/specs/views/Card/CardDescription-test.js b/test/specs/views/Card/CardDescription-test.js index 0804aea540..d59f9b9f2f 100644 --- a/test/specs/views/Card/CardDescription-test.js +++ b/test/specs/views/Card/CardDescription-test.js @@ -1,8 +1,8 @@ import faker from 'faker' import React from 'react' -import * as common from 'test/specs/commonTests' import CardDescription from 'src/views/Card/CardDescription' +import * as common from 'test/specs/commonTests' describe('CardDescription', () => { common.isConformant(CardDescription) diff --git a/test/specs/views/Card/CardGroup-test.js b/test/specs/views/Card/CardGroup-test.js index 909afe1e20..b3b0a82b89 100644 --- a/test/specs/views/Card/CardGroup-test.js +++ b/test/specs/views/Card/CardGroup-test.js @@ -1,15 +1,18 @@ import faker from 'faker' import React from 'react' -import * as common from 'test/specs/commonTests' + import CardGroup from 'src/views/Card/CardGroup' +import * as common from 'test/specs/commonTests' describe('CardGroup', () => { common.isConformant(CardGroup) common.hasUIClassName(CardGroup) + common.rendersChildren(CardGroup) + common.implementsWidthProp(CardGroup, { propKey: 'itemsPerRow', canEqual: false }) + common.propKeyOnlyToClassName(CardGroup, 'doubling') common.propKeyOnlyToClassName(CardGroup, 'stackable') - common.rendersChildren(CardGroup) describe('renders children', () => { const firstText = faker.hacker.phrase() diff --git a/test/specs/views/Card/CardHeader-test.js b/test/specs/views/Card/CardHeader-test.js index 79716ad52c..c232242b46 100644 --- a/test/specs/views/Card/CardHeader-test.js +++ b/test/specs/views/Card/CardHeader-test.js @@ -1,8 +1,8 @@ import faker from 'faker' import React from 'react' -import * as common from 'test/specs/commonTests' import CardHeader from 'src/views/Card/CardHeader' +import * as common from 'test/specs/commonTests' describe('CardHeader', () => { common.isConformant(CardHeader) diff --git a/test/specs/views/Card/CardMeta-test.js b/test/specs/views/Card/CardMeta-test.js index f35568bbe5..d88492942a 100644 --- a/test/specs/views/Card/CardMeta-test.js +++ b/test/specs/views/Card/CardMeta-test.js @@ -1,8 +1,8 @@ import faker from 'faker' import React from 'react' -import * as common from 'test/specs/commonTests' import CardMeta from 'src/views/Card/CardMeta' +import * as common from 'test/specs/commonTests' describe('CardMeta', () => { common.isConformant(CardMeta)