From 5652ee54e684b7a8782cad9cf52dde1cf172bf87 Mon Sep 17 00:00:00 2001 From: Alexander Fedyashov Date: Fri, 13 Jan 2017 10:59:08 +0200 Subject: [PATCH 1/5] style(Checkbox|Flag|Image|Radio): propTypes cleanups --- src/addons/Radio/Radio.js | 11 ++++------ src/addons/Radio/index.d.ts | 16 ++++++++++++-- src/elements/Flag/Flag.js | 13 ++++++----- src/elements/Flag/index.d.ts | 12 +++++------ src/elements/Image/Image.js | 23 +++++++------------- src/elements/Image/ImageGroup.js | 7 ++---- src/elements/Image/index.d.ts | 30 ++++++++++++-------------- src/modules/Checkbox/Checkbox.js | 28 +++++++++--------------- src/modules/Checkbox/index.d.ts | 23 ++++++++++---------- src/views/Item/ItemImage.js | 5 +++-- test/specs/modules/Embed/Embed-test.js | 2 +- 11 files changed, 79 insertions(+), 91 deletions(-) diff --git a/src/addons/Radio/Radio.js b/src/addons/Radio/Radio.js index 49e45fd2e7..b81fed5c16 100644 --- a/src/addons/Radio/Radio.js +++ b/src/addons/Radio/Radio.js @@ -1,4 +1,4 @@ -import React, { PropTypes } from 'react' +import React from 'react' import { getUnhandledProps, META } from '../../lib' import Checkbox from '../../modules/Checkbox' @@ -23,20 +23,17 @@ function Radio(props) { Radio._meta = { name: 'Radio', type: META.TYPES.ADDON, - props: { - type: Checkbox._meta.props.type, - }, } Radio.propTypes = { - /** Format to emphasize the current selection state */ + /** Format to emphasize the current selection state. */ slider: Checkbox.propTypes.slider, - /** Format to show an on or off choice */ + /** Format to show an on or off choice. */ toggle: Checkbox.propTypes.toggle, /** HTML input type, either checkbox or radio. */ - type: PropTypes.oneOf(Radio._meta.props.type), + type: Checkbox.propTypes.type, } Radio.defaultProps = { diff --git a/src/addons/Radio/index.d.ts b/src/addons/Radio/index.d.ts index c4a1841dd4..c6feb11161 100644 --- a/src/addons/Radio/index.d.ts +++ b/src/addons/Radio/index.d.ts @@ -1,4 +1,16 @@ -import { CheckboxProps } from '../../modules/Checkbox/index'; import * as React from 'react'; -export const Radio: React.ComponentClass; +interface RadioProps { + [key: string]: any; + + /** Format to emphasize the current selection state. */ + slider?: boolean; + + /** Format to show an on or off choice. */ + toggle?: boolean; + + /** HTML input type, either checkbox or radio. */ + type?: 'checkbox' | 'radio'; +} + +export const Radio: React.StatelessComponent; diff --git a/src/elements/Flag/Flag.js b/src/elements/Flag/Flag.js index 2c3ea9ac22..e00ea6410d 100644 --- a/src/elements/Flag/Flag.js +++ b/src/elements/Flag/Flag.js @@ -53,9 +53,12 @@ const names = [ 'ye', 'yemen', 'yt', 'mayotte', 'za', 'south africa', 'zm', 'zambia', 'zw', 'zimbabwe', ] +/** + * A flag is is used to represent a political state. + **/ function Flag(props) { const { className, name } = props - const classes = cx(name, className, 'flag') + const classes = cx(name, 'flag', className) const rest = getUnhandledProps(Flag, props) const ElementType = getElementType(Flag, props) @@ -65,9 +68,6 @@ function Flag(props) { Flag._meta = { name: 'Flag', type: META.TYPES.ELEMENT, - props: { - name: names, - }, } Flag.propTypes = { @@ -77,8 +77,8 @@ Flag.propTypes = { /** Additional classes. */ className: PropTypes.string, - /** Flag name, can use the two digit country code, the full name, or a common alias */ - name: customPropTypes.suggest(Flag._meta.props.name), + /** Flag name, can use the two digit country code, the full name, or a common alias. */ + name: customPropTypes.suggest(names), } Flag.defaultProps = { @@ -88,4 +88,3 @@ Flag.defaultProps = { Flag.create = createShorthandFactory(Flag, value => ({ name: value })) export default Flag - diff --git a/src/elements/Flag/index.d.ts b/src/elements/Flag/index.d.ts index e156339b20..363b556120 100644 --- a/src/elements/Flag/index.d.ts +++ b/src/elements/Flag/index.d.ts @@ -1,9 +1,8 @@ -import { ReactMouseEvents, SemanticCOUNTRY } from '../..'; import * as React from 'react'; +import { SemanticCOUNTRY } from '../..'; -// Flag -// ---------------------------------- -interface FlagProps extends ReactMouseEvents { +interface FlagProps { + [key: string]: any; /** An element type to render as (string or function). */ as?: any; @@ -11,9 +10,8 @@ interface FlagProps extends ReactMouseEvents { /** Additional classes. */ className?: string; - /** Flag name, can use the two digit country code, the full name, or a common alias */ + /** Flag name, can use the two digit country code, the full name, or a common alias. */ name: SemanticCOUNTRY, } -export class Flag extends React.Component { -} \ No newline at end of file +export const Flag : React.StatelessComponent; diff --git a/src/elements/Image/Image.js b/src/elements/Image/Image.js index ea05824658..778189618a 100644 --- a/src/elements/Image/Image.js +++ b/src/elements/Image/Image.js @@ -95,13 +95,6 @@ Image.Group = ImageGroup Image._meta = { name: 'Image', type: META.TYPES.ELEMENT, - props: { - verticalAlign: SUI.VERTICAL_ALIGNMENTS, - floated: SUI.FLOATS, - shape: ['rounded', 'circular'], - size: SUI.SIZES, - spaced: ['left', 'right'], - }, } Image.propTypes = { @@ -133,7 +126,7 @@ Image.propTypes = { dimmer: customPropTypes.itemShorthand, /** An image can sit to the left or right of other content. */ - floated: PropTypes.oneOf(Image._meta.props.floated), + floated: PropTypes.oneOf(SUI.FLOATS), /** An image can take up the width of its container. */ fluid: customPropTypes.every([ @@ -160,15 +153,15 @@ Image.propTypes = { label: customPropTypes.itemShorthand, /** An image may appear rounded or circular. */ - shape: PropTypes.oneOf(Image._meta.props.shape), + shape: PropTypes.oneOf(['rounded', 'circular']), /** An image may appear at different sizes. */ - size: PropTypes.oneOf(Image._meta.props.size), + size: PropTypes.oneOf(SUI.SIZES), /** An image can specify that it needs an additional spacing to separate it from nearby content. */ spaced: PropTypes.oneOfType([ PropTypes.bool, - PropTypes.oneOf(Image._meta.props.spaced), + PropTypes.oneOf(['left', 'right']), ]), /** Specifies the URL of the image. */ @@ -177,16 +170,16 @@ Image.propTypes = { /** Whether or not to add the ui className. */ ui: PropTypes.bool, - /** An image can specify its vertical alignment */ - verticalAlign: PropTypes.oneOf(Image._meta.props.verticalAlign), + /** An image can specify its vertical alignment. */ + verticalAlign: PropTypes.oneOf(SUI.VERTICAL_ALIGNMENTS), - /** The img element width attribute */ + /** The img element width attribute. */ width: PropTypes.oneOfType([ PropTypes.string, PropTypes.number, ]), - /** An image can render wrapped in a `div.ui.image` as alternative HTML markup */ + /** An image can render wrapped in a `div.ui.image` as alternative HTML markup. */ wrapped: customPropTypes.every([ PropTypes.bool, // these props wrap the image in an a tag already diff --git a/src/elements/Image/ImageGroup.js b/src/elements/Image/ImageGroup.js index b6b2ba8cea..a8ce3cc9c1 100644 --- a/src/elements/Image/ImageGroup.js +++ b/src/elements/Image/ImageGroup.js @@ -10,7 +10,7 @@ import { } from '../../lib' /** - * A group of images + * A group of images. */ function ImageGroup(props) { const { children, className, size } = props @@ -25,9 +25,6 @@ ImageGroup._meta = { name: 'ImageGroup', parent: 'Image', type: META.TYPES.ELEMENT, - props: { - size: SUI.SIZES, - }, } ImageGroup.propTypes = { @@ -41,7 +38,7 @@ ImageGroup.propTypes = { className: PropTypes.string, /** A group of images can be formatted to have the same size. */ - size: PropTypes.oneOf(ImageGroup._meta.props.size), + size: PropTypes.oneOf(SUI.SIZES), } export default ImageGroup diff --git a/src/elements/Image/index.d.ts b/src/elements/Image/index.d.ts index e6121bfbe3..f6945bb305 100644 --- a/src/elements/Image/index.d.ts +++ b/src/elements/Image/index.d.ts @@ -1,6 +1,5 @@ import { LabelProps } from '../Label'; import { - ReactMouseEvents, SemanticFLOATS, SemanticSIZES, SemanticVERTICALALIGNMENTS, @@ -9,10 +8,8 @@ import { } from '../..'; import * as React from 'react'; - -// Image -// ---------------------------------- -export interface ImageProps extends ReactMouseEvents { +export interface ImageProps { + [key: string]: any; /** Alternate text for the image specified. */ alt?: string; @@ -36,7 +33,7 @@ export interface ImageProps extends ReactMouseEvents { disabled?: boolean; /** Shorthand for Dimmer. */ - dimmer?:any; + dimmer?: any; /** An image can sit to the left or right of other content. */ floated?: SemanticFLOATS; @@ -54,10 +51,10 @@ export interface ImageProps extends ReactMouseEvents { inline?: boolean; /** Shorthand for Label. */ - label?: LabelProps; + label?: any | LabelProps; /** An image may appear rounded or circular. */ - shape?: boolean |'rounded'|'circular'; + shape?: 'rounded'|'circular'; /** An image may appear at different sizes. */ size?: SemanticSIZES; @@ -71,24 +68,25 @@ export interface ImageProps extends ReactMouseEvents { /** Whether or not to add the ui className. */ ui?: boolean; - /** An image can specify its vertical alignment */ + /** An image can specify its vertical alignment. */ verticalAlign?: SemanticVERTICALALIGNMENTS; - /** The img element width attribute */ + /** The img element width attribute. */ width?: number|SemanticWIDTHSSTRING| SemanticWIDTHSNUMBER; - /** An image can render wrapped in a `div.ui.image` as alternative HTML markup */ - wrapped?: any; + /** An image can render wrapped in a `div.ui.image` as alternative HTML markup. */ + wrapped?: boolean; } -interface ImageClass extends React.ComponentClass { +interface ImageComponent extends React.StatelessComponent { Group: typeof ImageGroup; } -export const Image: ImageClass; +export const Image: ImageComponent; interface ImageGroupProps { - + [key: string]: any; + /** An element type to render as (string or function). */ as?: any; @@ -101,4 +99,4 @@ interface ImageGroupProps { /** A group of images can be formatted to have the same size. */ size?: SemanticSIZES; } -export const ImageGroup: React.ComponentClass; +export const ImageGroup: React.StatelessComponent; diff --git a/src/modules/Checkbox/Checkbox.js b/src/modules/Checkbox/Checkbox.js index a1d2693bb1..51ef071d3d 100644 --- a/src/modules/Checkbox/Checkbox.js +++ b/src/modules/Checkbox/Checkbox.js @@ -14,19 +14,8 @@ import { } from '../../lib' const debug = makeDebugger('checkbox') -const _meta = { - name: 'Checkbox', - type: META.TYPES.MODULE, - props: { - type: [ - 'checkbox', - 'radio', - ], - }, -} - /** - * A checkbox allows a user to select a value from a small set of options, often binary + * A checkbox allows a user to select a value from a small set of options, often binary. * @see Form * @see Radio */ @@ -78,29 +67,29 @@ export default class Checkbox extends Component { */ onClick: PropTypes.func, - /** Format as a radio element. This means it is an exclusive option.*/ + /** Format as a radio element. This means it is an exclusive option. */ radio: customPropTypes.every([ PropTypes.bool, customPropTypes.disallow(['slider', 'toggle']), ]), - /** A checkbox can be read-only and unable to change states */ + /** A checkbox can be read-only and unable to change states. */ readOnly: PropTypes.bool, - /** Format to emphasize the current selection state */ + /** Format to emphasize the current selection state. */ slider: customPropTypes.every([ PropTypes.bool, customPropTypes.disallow(['radio', 'toggle']), ]), - /** Format to show an on or off choice */ + /** Format to show an on or off choice. */ toggle: customPropTypes.every([ PropTypes.bool, customPropTypes.disallow(['radio', 'slider']), ]), /** HTML input type, either checkbox or radio. */ - type: PropTypes.oneOf(_meta.props.type), + type: PropTypes.oneOf(['checkbox', 'radio']), /** The HTML input value. */ value: PropTypes.string, @@ -121,7 +110,10 @@ export default class Checkbox extends Component { 'indeterminate', ] - static _meta = _meta + static _meta = { + name: 'Checkbox', + type: META.TYPES.MODULE, + } state = {} diff --git a/src/modules/Checkbox/index.d.ts b/src/modules/Checkbox/index.d.ts index fd8657e349..77eb9677af 100644 --- a/src/modules/Checkbox/index.d.ts +++ b/src/modules/Checkbox/index.d.ts @@ -1,6 +1,8 @@ import * as React from 'react'; +import {LabelProps} from '../../elements/Label'; export interface CheckboxProps { + [key: string]: any; /** An element type to render as (string or function). */ as?: any; @@ -27,7 +29,7 @@ export interface CheckboxProps { indeterminate?: boolean; /** The text of the associated label element. */ - label?: string; + label?: any | LabelProps; /** The HTML input name. */ name?: string; @@ -48,24 +50,23 @@ export interface CheckboxProps { */ onClick?: (e: React.MouseEvent, data: this) => void; - /** Format as a radio element. This means it is an exclusive option.*/ - radio?: any; + /** Format as a radio element. This means it is an exclusive option. */ + radio?: boolean; - /** A checkbox can be read-only and unable to change states */ + /** A checkbox can be read-only and unable to change states. */ readOnly?: boolean; - /** Format to emphasize the current selection state */ - slider?: any; + /** Format to emphasize the current selection state. */ + slider?: boolean; - /** Format to show an on or off choice */ - toggle?: any; + /** Format to show an on or off choice. */ + toggle?: boolean; /** HTML input type, either checkbox or radio. */ type?: 'checkbox' | 'radio'; /** The HTML input value. */ - value?: string; + value?: number|string; } -export class Checkbox extends React.Component { -} +export const Checkbox: React.ComponentClass; \ No newline at end of file diff --git a/src/views/Item/ItemImage.js b/src/views/Item/ItemImage.js index 93c6892632..3993083790 100644 --- a/src/views/Item/ItemImage.js +++ b/src/views/Item/ItemImage.js @@ -1,4 +1,5 @@ -import React, { PropTypes } from 'react' +import React from 'react' + import { META, getUnhandledProps, @@ -23,7 +24,7 @@ ItemImage._meta = { ItemImage.propTypes = { /** An image may appear at different sizes */ - size: PropTypes.oneOf(Image._meta.props.size), + size: Image.propTypes.size, } export default ItemImage diff --git a/test/specs/modules/Embed/Embed-test.js b/test/specs/modules/Embed/Embed-test.js index a1c7fdd27a..7cb6f9357d 100644 --- a/test/specs/modules/Embed/Embed-test.js +++ b/test/specs/modules/Embed/Embed-test.js @@ -8,7 +8,7 @@ const assertIframeSrc = (props, srcPart) => { const { id = faker.random.word(), source = 'youtube', - ...rest, + ...rest } = props shallow() From e28f64f3cbe3048f4c84abd99ab1effa9c21df25 Mon Sep 17 00:00:00 2001 From: Alexander Fedyashov Date: Fri, 13 Jan 2017 12:05:50 +0200 Subject: [PATCH 2/5] chore(commonTest): remove obsolete assertions --- test/specs/commonTests.js | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/test/specs/commonTests.js b/test/specs/commonTests.js index 84c1429445..67bce84cb2 100644 --- a/test/specs/commonTests.js +++ b/test/specs/commonTests.js @@ -893,7 +893,6 @@ export const implementsTextAlignProp = (Component, options = {}) => { * @param {Object} [options.requiredProps={}] Props required to render the component. */ export const implementsVerticalAlignProp = (Component, options = {}) => { - const { requiredProps = {} } = options const { assertRequired } = commonTestHelpers('implementsVerticalAlignProp', Component) describe('verticalAlign (common)', () => { @@ -901,13 +900,6 @@ export const implementsVerticalAlignProp = (Component, options = {}) => { _noDefaultClassNameFromProp(Component, 'verticalAlign', options) _noClassNameFromBoolProps(Component, 'verticalAlign', options) - - _.each(Component._meta.props.verticalAlign, (propVal) => { - it(`adds "${propVal} aligned" to className`, () => { - shallow() - .should.have.className(`${propVal} ${'aligned'}`) - }) - }) }) } @@ -1038,10 +1030,6 @@ export const propKeyOrValueAndKeyToClassName = (Component, propKey, options = {} wrapper.should.not.have.className(className) wrapper.should.not.have.className('true') wrapper.should.not.have.className('false') - - _.each(_.get(Component, `_meta.props[${propKey}]`), propVal => { - wrapper.should.not.have.className(propVal) - }) }) }) } From f99f555f8d51cc2b9921a6b9f8738e9b85613311 Mon Sep 17 00:00:00 2001 From: Alexander Fedyashov Date: Fri, 13 Jan 2017 12:09:28 +0200 Subject: [PATCH 3/5] fix(EmbedTest): fix lint issue --- test/specs/modules/Embed/Embed-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/specs/modules/Embed/Embed-test.js b/test/specs/modules/Embed/Embed-test.js index 7cb6f9357d..a1c7fdd27a 100644 --- a/test/specs/modules/Embed/Embed-test.js +++ b/test/specs/modules/Embed/Embed-test.js @@ -8,7 +8,7 @@ const assertIframeSrc = (props, srcPart) => { const { id = faker.random.word(), source = 'youtube', - ...rest + ...rest, } = props shallow() From 2646d2d251d1a856e4fdd9c6de1e61ccf7be324c Mon Sep 17 00:00:00 2001 From: Alexander Fedyashov Date: Tue, 17 Jan 2017 14:12:36 +0200 Subject: [PATCH 4/5] test(commonTest): update commonTests --- src/collections/Menu/Menu.js | 2 +- src/elements/Flag/Flag.js | 2 +- src/elements/List/List.js | 2 +- src/views/Item/Item.js | 2 +- src/views/Item/ItemContent.js | 2 +- src/views/Item/ItemDescription.js | 2 +- src/views/Item/ItemExtra.js | 2 +- src/views/Item/ItemGroup.js | 2 +- src/views/Item/ItemHeader.js | 2 +- src/views/Item/ItemImage.js | 2 +- src/views/Item/ItemMeta.js | 2 +- test/specs/collections/Grid/Grid-test.js | 24 +++++++------ test/specs/collections/Menu/Menu-test.js | 19 ++++++----- test/specs/collections/Menu/MenuItem-test.js | 14 +++++--- .../specs/collections/Message/Message-test.js | 34 ++++++++----------- test/specs/collections/Table/Table-test.js | 14 +++++--- test/specs/commonTests.js | 25 ++++++++++++-- test/specs/elements/Button/Button-test.js | 21 +++++++----- test/specs/elements/Header/Header-test.js | 27 ++++++++------- test/specs/elements/Image/Image-test.js | 20 +++++------ test/specs/elements/Label/Label-test.js | 24 ++++++------- test/specs/elements/List/List-test.js | 11 +++--- test/specs/elements/Loader/Loader-test.js | 2 +- test/specs/elements/Rail/Rail-test.js | 4 +-- test/specs/elements/Segment/Segment-test.js | 16 ++++----- test/specs/modules/Dropdown/Dropdown-test.js | 4 ++- test/specs/modules/Embed/Embed-test.js | 2 +- test/specs/views/Item/ItemGroup-test.js | 3 +- 28 files changed, 163 insertions(+), 123 deletions(-) diff --git a/src/collections/Menu/Menu.js b/src/collections/Menu/Menu.js index c3f3a8b303..afbfaa6206 100644 --- a/src/collections/Menu/Menu.js +++ b/src/collections/Menu/Menu.js @@ -35,7 +35,7 @@ const _meta = { /** * A menu displays grouped navigation actions. - **/ + */ class Menu extends Component { static propTypes = { /** An element type to render as (string or function). */ diff --git a/src/elements/Flag/Flag.js b/src/elements/Flag/Flag.js index e00ea6410d..201ca0093b 100644 --- a/src/elements/Flag/Flag.js +++ b/src/elements/Flag/Flag.js @@ -55,7 +55,7 @@ const names = [ /** * A flag is is used to represent a political state. - **/ + */ function Flag(props) { const { className, name } = props const classes = cx(name, 'flag', className) diff --git a/src/elements/List/List.js b/src/elements/List/List.js index ff1d741409..a224591ec8 100644 --- a/src/elements/List/List.js +++ b/src/elements/List/List.js @@ -22,7 +22,7 @@ import ListList from './ListList' /** * A list groups related content - **/ + */ function List(props) { const { animated, diff --git a/src/views/Item/Item.js b/src/views/Item/Item.js index 84415efec8..e62ba24cca 100644 --- a/src/views/Item/Item.js +++ b/src/views/Item/Item.js @@ -19,7 +19,7 @@ import ItemMeta from './ItemMeta' /** * An item view presents large collections of site content for display - **/ + */ function Item(props) { const { children, className, content, description, extra, header, image, meta } = props const classes = cx(className, 'item') diff --git a/src/views/Item/ItemContent.js b/src/views/Item/ItemContent.js index 7dc05de80e..d9e8b12773 100644 --- a/src/views/Item/ItemContent.js +++ b/src/views/Item/ItemContent.js @@ -18,7 +18,7 @@ import ItemMeta from './ItemMeta' /** * An item can contain content - **/ + */ function ItemContent(props) { const { children, className, content, description, extra, header, meta, verticalAlign } = props const classes = cx( diff --git a/src/views/Item/ItemDescription.js b/src/views/Item/ItemDescription.js index 09144f0993..aaf5c35772 100644 --- a/src/views/Item/ItemDescription.js +++ b/src/views/Item/ItemDescription.js @@ -11,7 +11,7 @@ import { /** * An item can contain a description with a single or multiple paragraphs - **/ + */ function ItemDescription(props) { const { children, className, content } = props const classes = cx(className, 'description') diff --git a/src/views/Item/ItemExtra.js b/src/views/Item/ItemExtra.js index 1ab60df41a..3911f4c9f9 100644 --- a/src/views/Item/ItemExtra.js +++ b/src/views/Item/ItemExtra.js @@ -11,7 +11,7 @@ import { /** * An item can contain extra content meant to be formatted separately from the main content - **/ + */ function ItemExtra(props) { const { children, className, content } = props const classes = cx(className, 'extra') diff --git a/src/views/Item/ItemGroup.js b/src/views/Item/ItemGroup.js index 5e61c89039..ae4041d753 100644 --- a/src/views/Item/ItemGroup.js +++ b/src/views/Item/ItemGroup.js @@ -14,7 +14,7 @@ import Item from './Item' /** * A group of items - **/ + */ function ItemGroup(props) { const { children, className, divided, items, link, relaxed } = props const classes = cx( diff --git a/src/views/Item/ItemHeader.js b/src/views/Item/ItemHeader.js index ae2f2a5655..9852299f0e 100644 --- a/src/views/Item/ItemHeader.js +++ b/src/views/Item/ItemHeader.js @@ -11,7 +11,7 @@ import { /** * An item can contain a header - **/ + */ function ItemHeader(props) { const { children, className, content } = props const classes = cx(className, 'header') diff --git a/src/views/Item/ItemImage.js b/src/views/Item/ItemImage.js index 3993083790..15c04f8571 100644 --- a/src/views/Item/ItemImage.js +++ b/src/views/Item/ItemImage.js @@ -8,7 +8,7 @@ import Image from '../../elements/Image' /** * An item can contain an image - **/ + */ function ItemImage(props) { const { size } = props const rest = getUnhandledProps(ItemImage, props) diff --git a/src/views/Item/ItemMeta.js b/src/views/Item/ItemMeta.js index 5a29091308..2dae69c5bf 100644 --- a/src/views/Item/ItemMeta.js +++ b/src/views/Item/ItemMeta.js @@ -11,7 +11,7 @@ import { /** * An item can contain content metadata. - **/ + */ function ItemMeta(props) { const { children, className, content } = props const classes = cx(className, 'meta') diff --git a/test/specs/collections/Grid/Grid-test.js b/test/specs/collections/Grid/Grid-test.js index a9e7b997b0..485fb42278 100644 --- a/test/specs/collections/Grid/Grid-test.js +++ b/test/specs/collections/Grid/Grid-test.js @@ -10,20 +10,24 @@ describe('Grid', () => { common.hasSubComponents(Grid, [GridRow, GridColumn]) common.rendersChildren(Grid) + common.implementsTextAlignProp(Grid) + common.implementsVerticalAlignProp(Grid) + common.implementsWidthProp(Grid, { + canEqual: true, + propKey: 'columns', + widthClass: 'column', + }) + + common.propKeyAndValueToClassName(Grid, 'reversed') + common.propKeyOnlyToClassName(Grid, 'centered') common.propKeyOnlyToClassName(Grid, 'container') common.propKeyOnlyToClassName(Grid, 'doubling') common.propKeyOnlyToClassName(Grid, 'stackable') common.propKeyOnlyToClassName(Grid, 'stretched') - common.propKeyOrValueAndKeyToClassName(Grid, 'celled') - common.propKeyOrValueAndKeyToClassName(Grid, 'divided') - common.propKeyOrValueAndKeyToClassName(Grid, 'padded') - common.propKeyOrValueAndKeyToClassName(Grid, 'relaxed') - - common.propKeyAndValueToClassName(Grid, 'reversed') - - common.implementsTextAlignProp(Grid) - common.implementsVerticalAlignProp(Grid) - common.implementsWidthProp(Grid, { propKey: 'columns', widthClass: 'column', canEqual: true }) + common.propKeyOrValueAndKeyToClassName(Grid, 'celled', ['internally']) + common.propKeyOrValueAndKeyToClassName(Grid, 'divided', ['vertically']) + common.propKeyOrValueAndKeyToClassName(Grid, 'padded', ['horizontally', 'vertically']) + common.propKeyOrValueAndKeyToClassName(Grid, 'relaxed', ['very']) }) diff --git a/test/specs/collections/Menu/Menu-test.js b/test/specs/collections/Menu/Menu-test.js index 9e509eac09..626260a9fc 100644 --- a/test/specs/collections/Menu/Menu-test.js +++ b/test/specs/collections/Menu/Menu-test.js @@ -11,27 +11,30 @@ describe('Menu', () => { common.isConformant(Menu) common.hasUIClassName(Menu) common.hasSubComponents(Menu, [MenuHeader, MenuItem, MenuMenu]) + common.rendersChildren(Menu) common.implementsWidthProp(Menu, { propKey: 'widths', canEqual: false }) - common.propKeyOrValueAndKeyToClassName(Menu, 'attached') + + common.propKeyAndValueToClassName(Menu, 'fixed') + common.propKeyOnlyToClassName(Menu, 'borderless') - common.propValueOnlyToClassName(Menu, 'color') common.propKeyOnlyToClassName(Menu, 'compact') - common.propKeyAndValueToClassName(Menu, 'fixed') - common.propKeyOrValueAndKeyToClassName(Menu, 'floated') common.propKeyOnlyToClassName(Menu, 'fluid') - common.propKeyOrValueAndKeyToClassName(Menu, 'icon') common.propKeyOnlyToClassName(Menu, 'inverted') common.propKeyOnlyToClassName(Menu, 'pagination') common.propKeyOnlyToClassName(Menu, 'pointing') common.propKeyOnlyToClassName(Menu, 'secondary') common.propKeyOnlyToClassName(Menu, 'stackable') - common.propKeyOrValueAndKeyToClassName(Menu, 'tabular') common.propKeyOnlyToClassName(Menu, 'text') - common.propValueOnlyToClassName(Menu, 'size') common.propKeyOnlyToClassName(Menu, 'vertical') - common.rendersChildren(Menu) + common.propKeyOrValueAndKeyToClassName(Menu, 'attached', ['top', 'bottom']) + common.propKeyOrValueAndKeyToClassName(Menu, 'floated', ['right']) + common.propKeyOrValueAndKeyToClassName(Menu, 'icon', ['labeled']) + common.propKeyOrValueAndKeyToClassName(Menu, 'tabular', ['right']) + + common.propValueOnlyToClassName(Menu, 'color') + common.propValueOnlyToClassName(Menu, 'size') it('renders a `div` by default', () => { shallow() diff --git a/test/specs/collections/Menu/MenuItem-test.js b/test/specs/collections/Menu/MenuItem-test.js index 2c766a6ae9..236811c50d 100644 --- a/test/specs/collections/Menu/MenuItem-test.js +++ b/test/specs/collections/Menu/MenuItem-test.js @@ -7,16 +7,20 @@ import { sandbox } from 'test/utils' describe('MenuItem', () => { common.isConformant(MenuItem) - common.implementsIconProp(MenuItem) + common.rendersChildren(MenuItem) + common.implementsCreateMethod(MenuItem) + common.implementsIconProp(MenuItem) + common.propKeyOnlyToClassName(MenuItem, 'active') - common.propValueOnlyToClassName(MenuItem, 'color') - common.propKeyOrValueAndKeyToClassName(MenuItem, 'fitted') - common.propKeyOnlyToClassName(MenuItem, 'icon') common.propKeyOnlyToClassName(MenuItem, 'header') + common.propKeyOnlyToClassName(MenuItem, 'icon') common.propKeyOnlyToClassName(MenuItem, 'link') + + common.propKeyOrValueAndKeyToClassName(MenuItem, 'fitted', ['horizontally', 'vertically']) + + common.propValueOnlyToClassName(MenuItem, 'color') common.propValueOnlyToClassName(MenuItem, 'position') - common.rendersChildren(MenuItem) it('renders a `div` by default', () => { shallow() diff --git a/test/specs/collections/Message/Message-test.js b/test/specs/collections/Message/Message-test.js index c6fcc990c9..170dbe4358 100644 --- a/test/specs/collections/Message/Message-test.js +++ b/test/specs/collections/Message/Message-test.js @@ -12,11 +12,13 @@ describe('Message', () => { common.isConformant(Message) common.hasUIClassName(Message) common.hasSubComponents(Message, [MessageContent, MessageHeader, MessageList]) + common.rendersChildren(Message) + common.implementsIconProp(Message) common.implementsShorthandProp(Message, { - propKey: 'list', - ShorthandComponent: MessageList, - mapValueToProps: val => ({ items: val }), + propKey: 'content', + ShorthandComponent: 'p', + mapValueToProps: val => ({ children: val }), }) common.implementsShorthandProp(Message, { propKey: 'header', @@ -28,29 +30,23 @@ describe('Message', () => { ShorthandComponent: MessageList, mapValueToProps: val => ({ items: val }), }) - common.implementsShorthandProp(Message, { - propKey: 'content', - ShorthandComponent: 'p', - mapValueToProps: val => ({ children: val }), - }) - common.propValueOnlyToClassName(Message, 'size') - common.propValueOnlyToClassName(Message, 'color') - common.propKeyOnlyToClassName(Message, 'icon') - common.propKeyOnlyToClassName(Message, 'hidden') - common.propKeyOnlyToClassName(Message, 'visible') - common.propKeyOnlyToClassName(Message, 'floating') common.propKeyOnlyToClassName(Message, 'compact') - common.propKeyOnlyToClassName(Message, 'warning') + common.propKeyOnlyToClassName(Message, 'error') + common.propKeyOnlyToClassName(Message, 'floating') + common.propKeyOnlyToClassName(Message, 'hidden') + common.propKeyOnlyToClassName(Message, 'icon') common.propKeyOnlyToClassName(Message, 'info') + common.propKeyOnlyToClassName(Message, 'negative') common.propKeyOnlyToClassName(Message, 'positive') common.propKeyOnlyToClassName(Message, 'success') - common.propKeyOnlyToClassName(Message, 'negative') - common.propKeyOnlyToClassName(Message, 'error') + common.propKeyOnlyToClassName(Message, 'visible') + common.propKeyOnlyToClassName(Message, 'warning') - common.propKeyOrValueAndKeyToClassName(Message, 'attached') + common.propKeyOrValueAndKeyToClassName(Message, 'attached', ['bottom']) - common.rendersChildren(Message) + common.propValueOnlyToClassName(Message, 'size') + common.propValueOnlyToClassName(Message, 'color') describe('header', () => { it('adds MessageContent when defined', () => { diff --git a/test/specs/collections/Table/Table-test.js b/test/specs/collections/Table/Table-test.js index 24fd0b8d48..618b2c6ddd 100644 --- a/test/specs/collections/Table/Table-test.js +++ b/test/specs/collections/Table/Table-test.js @@ -15,7 +15,11 @@ describe('Table', () => { common.hasSubComponents(Table, [TableBody, TableCell, TableFooter, TableHeader, TableHeaderCell, TableRow]) common.rendersChildren(Table) - common.implementsWidthProp(Table, { propKey: 'columns', widthClass: 'column', canEqual: false }) + common.implementsWidthProp(Table, { + canEqual: false, + propKey: 'columns', + widthClass: 'column', + }) common.propKeyOnlyToClassName(Table, 'celled') common.propKeyOnlyToClassName(Table, 'collapsing') @@ -31,10 +35,10 @@ describe('Table', () => { common.propKeyOnlyToClassName(Table, 'structured') common.propKeyOnlyToClassName(Table, 'unstackable') - common.propKeyOrValueAndKeyToClassName(Table, 'attached') - common.propKeyOrValueAndKeyToClassName(Table, 'basic') - common.propKeyOrValueAndKeyToClassName(Table, 'compact') - common.propKeyOrValueAndKeyToClassName(Table, 'padded') + common.propKeyOrValueAndKeyToClassName(Table, 'attached', ['top', 'bottom']) + common.propKeyOrValueAndKeyToClassName(Table, 'basic', ['very']) + common.propKeyOrValueAndKeyToClassName(Table, 'compact', ['very']) + common.propKeyOrValueAndKeyToClassName(Table, 'padded', ['very']) common.propValueOnlyToClassName(Table, 'color') common.propValueOnlyToClassName(Table, 'size') diff --git a/test/specs/commonTests.js b/test/specs/commonTests.js index 67bce84cb2..1d94ccbcb2 100644 --- a/test/specs/commonTests.js +++ b/test/specs/commonTests.js @@ -4,7 +4,12 @@ import path from 'path' import React, { createElement, isValidElement } from 'react' import ReactDOMServer from 'react-dom/server' -import { createShorthand, META, numberToWord } from 'src/lib' +import { + createShorthand, + META, + numberToWord, + SUI, +} from 'src/lib' import { consoleUtil, sandbox, syntheticEvent } from 'test/utils' import * as semanticUIReact from 'semantic-ui-react' @@ -889,10 +894,12 @@ export const implementsTextAlignProp = (Component, options = {}) => { /** * Assert that a Component correctly implements the "verticalAlign" prop. * @param {React.Component|Function} Component The component to test. + * @param {array} [alignments] Array of possible alignment positions. * @param {Object} [options={}] * @param {Object} [options.requiredProps={}] Props required to render the component. */ -export const implementsVerticalAlignProp = (Component, options = {}) => { +export const implementsVerticalAlignProp = (Component, alignments = SUI.VERTICAL_ALIGNMENTS, options = {}) => { + const { requiredProps = {} } = options const { assertRequired } = commonTestHelpers('implementsVerticalAlignProp', Component) describe('verticalAlign (common)', () => { @@ -900,6 +907,13 @@ export const implementsVerticalAlignProp = (Component, options = {}) => { _noDefaultClassNameFromProp(Component, 'verticalAlign', options) _noClassNameFromBoolProps(Component, 'verticalAlign', options) + + _.each(alignments, propVal => { + it(`adds "${propVal} aligned" to className`, () => { + shallow() + .should.have.className(`${propVal} ${'aligned'}`) + }) + }) }) } @@ -1000,11 +1014,12 @@ export const propKeyAndValueToClassName = (Component, propKey, options = {}) => * Assert that a Component prop name or value convert to a className. * @param {React.Component|Function} Component The component to test. * @param {String} propKey A props key. + * @param {array} propValues Array of possible values of prop. * @param {Object} [options={}] * @param {Object} [options.requiredProps={}] Props required to render the component. * @param {Object} [options.className=propKey] The className to assert exists. */ -export const propKeyOrValueAndKeyToClassName = (Component, propKey, options = {}) => { +export const propKeyOrValueAndKeyToClassName = (Component, propKey, propValues, options = {}) => { const { className = propKey, requiredProps = {} } = options const { assertRequired } = commonTestHelpers('propKeyOrValueAndKeyToClassName', Component) @@ -1030,6 +1045,10 @@ export const propKeyOrValueAndKeyToClassName = (Component, propKey, options = {} wrapper.should.not.have.className(className) wrapper.should.not.have.className('true') wrapper.should.not.have.className('false') + + _.each(propValues, propVal => { + wrapper.should.not.have.className(propVal) + }) }) }) } diff --git a/test/specs/elements/Button/Button-test.js b/test/specs/elements/Button/Button-test.js index a022223804..ae7d08cf4e 100644 --- a/test/specs/elements/Button/Button-test.js +++ b/test/specs/elements/Button/Button-test.js @@ -13,6 +13,8 @@ describe('Button', () => { common.isConformant(Button) common.hasUIClassName(Button) common.hasSubComponents(Button, [ButtonContent, ButtonGroup, ButtonOr]) + common.rendersChildren(Button) + common.implementsCreateMethod(Button) common.implementsIconProp(Button) common.implementsLabelProp(Button, { @@ -22,28 +24,29 @@ describe('Button', () => { }, }) + common.propKeyAndValueToClassName(Button, 'floated') + common.propKeyOnlyToClassName(Button, 'active') - common.propKeyOrValueAndKeyToClassName(Button, 'animated') - common.propKeyOrValueAndKeyToClassName(Button, 'attached') common.propKeyOnlyToClassName(Button, 'basic') common.propKeyOnlyToClassName(Button, 'circular') - common.propValueOnlyToClassName(Button, 'color') common.propKeyOnlyToClassName(Button, 'compact') common.propKeyOnlyToClassName(Button, 'disabled') - common.propKeyAndValueToClassName(Button, 'floated') common.propKeyOnlyToClassName(Button, 'fluid') common.propKeyOnlyToClassName(Button, 'inverted') - common.propKeyOrValueAndKeyToClassName(Button, 'labelPosition', { - className: 'labeled', - }) common.propKeyOnlyToClassName(Button, 'loading') common.propKeyOnlyToClassName(Button, 'primary') common.propKeyOnlyToClassName(Button, 'negative') common.propKeyOnlyToClassName(Button, 'positive') common.propKeyOnlyToClassName(Button, 'secondary') - common.propValueOnlyToClassName(Button, 'size') - common.rendersChildren(Button) + common.propKeyOrValueAndKeyToClassName(Button, 'animated', ['fade', 'vertical']) + common.propKeyOrValueAndKeyToClassName(Button, 'attached', ['left', 'right', 'top', 'bottom']) + common.propKeyOrValueAndKeyToClassName(Button, 'labelPosition', ['right', 'left'], { + className: 'labeled', + }) + + common.propValueOnlyToClassName(Button, 'color') + common.propValueOnlyToClassName(Button, 'size') it('renders a button by default', () => { shallow(