Skip to content

Commit

Permalink
feat(ElementType): new wrapper for all elements
Browse files Browse the repository at this point in the history
  • Loading branch information
layershifter committed Nov 12, 2017
1 parent 6ef5af5 commit d117cf6
Show file tree
Hide file tree
Showing 35 changed files with 697 additions and 275 deletions.
22 changes: 12 additions & 10 deletions src/elements/Container/Container.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,19 @@ import React from 'react'
import {
childrenUtils,
customPropTypes,
getElementType,
ElementType,
getUnhandledProps,
META,
SUI,
useKeyOnly,
useTextAlignProp,
withComputedType,
} from '../../lib'

/**
* A container limits content to a maximum width.
*/
function Container(props) {
const InnerContainer = (props) => {
const {
children,
className,
Expand All @@ -33,8 +34,7 @@ function Container(props) {
'container',
className,
)
const rest = getUnhandledProps(Container, props)
const ElementType = getElementType(Container, props)
const rest = getUnhandledProps(InnerContainer, props, { passAs: true })

return (
<ElementType {...rest} className={classes}>
Expand All @@ -43,12 +43,7 @@ function Container(props) {
)
}

Container._meta = {
name: 'Container',
type: META.TYPES.ELEMENT,
}

Container.propTypes = {
InnerContainer.propTypes = {
/** An element type to render as (string or function). */
as: customPropTypes.as,

Expand All @@ -71,4 +66,11 @@ Container.propTypes = {
textAlign: PropTypes.oneOf(SUI.TEXT_ALIGNMENTS),
}

const Container = withComputedType()(InnerContainer)

Container._meta = {
name: 'Container',
type: META.TYPES.ELEMENT,
}

export default Container
44 changes: 24 additions & 20 deletions src/elements/Image/Image.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ import {
childrenUtils,
createShorthandFactory,
customPropTypes,
getElementType,
ElementType,
getUnhandledProps,
META,
SUI,
useKeyOnly,
useKeyOrValueAndKey,
useValueAndKey,
useVerticalAlignProp,
withComputedType,
} from '../../lib'
import Dimmer from '../../modules/Dimmer'
import Label from '../Label/Label'
Expand All @@ -25,8 +26,9 @@ import ImageGroup from './ImageGroup'
* An image is a graphic representation of something.
* @see Icon
*/
function Image(props) {
const InnerImage = (props) => {
const {
as,
alt,
avatar,
bordered,
Expand All @@ -50,7 +52,6 @@ function Image(props) {
src,
verticalAlign,
width,
wrapped,
ui,
} = props

Expand All @@ -72,22 +73,19 @@ function Image(props) {
'image',
className,
)
const rest = getUnhandledProps(Image, props)
const ElementType = getElementType(Image, props, () => {
if (!_.isNil(dimmer) || !_.isNil(label) || !_.isNil(wrapped) || !childrenUtils.isNil(children)) return 'div'
})
const rest = getUnhandledProps(InnerImage, props)

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

const rootProps = { ...rest, className: classes }
const rootProps = { ...rest, as, className: classes }
const imgTagProps = { alt, src, height, width }

if (ElementType === 'img') return <ElementType {...rootProps} {...imgTagProps} />
if (as === 'img') return <ElementType {...rootProps} {...imgTagProps} />

return (
<ElementType {...rootProps} href={href}>
Expand All @@ -98,14 +96,7 @@ function Image(props) {
)
}

Image.Group = ImageGroup

Image._meta = {
name: 'Image',
type: META.TYPES.ELEMENT,
}

Image.propTypes = {
InnerImage.propTypes = {
/** An element type to render as (string or function). */
as: customPropTypes.as,

Expand Down Expand Up @@ -197,11 +188,24 @@ Image.propTypes = {
wrapped: PropTypes.bool,
}

Image.defaultProps = {
InnerImage.defaultProps = {
as: 'img',
ui: true,
}

const computeType = ({ children, dimmer, label, wrapped }) => {
if (!_.isNil(dimmer) || !_.isNil(label) || !_.isNil(wrapped) || !childrenUtils.isNil(children)) return 'div'
}

const Image = withComputedType(computeType)(InnerImage)

Image.Group = ImageGroup

Image._meta = {
name: 'Image',
type: META.TYPES.ELEMENT,
}

Image.create = createShorthandFactory(Image, value => ({ src: value }))

export default Image
34 changes: 18 additions & 16 deletions src/elements/List/List.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ import React, { Component } from 'react'
import {
childrenUtils,
customPropTypes,
getElementType,
ElementType,
getUnhandledProps,
META,
SUI,
useKeyOnly,
useKeyOrValueAndKey,
useValueAndKey,
useVerticalAlignProp,
withComputedType,
} from '../../lib'
import ListContent from './ListContent'
import ListDescription from './ListDescription'
Expand All @@ -25,7 +26,7 @@ import ListList from './ListList'
/**
* A list groups related content.
*/
class List extends Component {
class InnerList extends Component {
static propTypes = {
/** An element type to render as (string or function). */
as: customPropTypes.as,
Expand Down Expand Up @@ -96,18 +97,6 @@ class List extends Component {
verticalAlign: PropTypes.oneOf(SUI.VERTICAL_ALIGNMENTS),
}

static _meta = {
name: 'List',
type: META.TYPES.ELEMENT,
}

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)
Expand Down Expand Up @@ -154,8 +143,7 @@ class List extends Component {
'list',
className,
)
const rest = getUnhandledProps(List, this.props)
const ElementType = getElementType(List, this.props)
const rest = getUnhandledProps(InnerList, this.props, { passAs: true })

if (!childrenUtils.isNil(children)) {
return <ElementType {...rest} role='list' className={classes}>{children}</ElementType>
Expand All @@ -173,4 +161,18 @@ class List extends Component {
}
}

const List = withComputedType()(InnerList)

List._meta = {
name: 'List',
type: META.TYPES.ELEMENT,
}

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

export default List
24 changes: 13 additions & 11 deletions src/elements/List/ListContent.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,21 @@ import {
childrenUtils,
createShorthandFactory,
customPropTypes,
getElementType,
ElementType,
getUnhandledProps,
META,
SUI,
useValueAndKey,
useVerticalAlignProp,
withComputedType,
} from '../../lib'
import ListDescription from './ListDescription'
import ListHeader from './ListHeader'

/**
* A list item can contain a content.
*/
function ListContent(props) {
const InnerListContent = (props) => {
const {
children,
className,
Expand All @@ -36,8 +37,7 @@ function ListContent(props) {
'content',
className,
)
const rest = getUnhandledProps(ListContent, props)
const ElementType = getElementType(ListContent, props)
const rest = getUnhandledProps(InnerListContent, props, { passAs: true })

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

Expand All @@ -50,13 +50,7 @@ function ListContent(props) {
)
}

ListContent._meta = {
name: 'ListContent',
parent: 'List',
type: META.TYPES.ELEMENT,
}

ListContent.propTypes = {
InnerListContent.propTypes = {
/** An element type to render as (string or function). */
as: customPropTypes.as,

Expand All @@ -82,6 +76,14 @@ ListContent.propTypes = {
verticalAlign: PropTypes.oneOf(SUI.VERTICAL_ALIGNMENTS),
}

const ListContent = withComputedType()(InnerListContent)

ListContent._meta = {
name: 'ListContent',
parent: 'List',
type: META.TYPES.ELEMENT,
}

ListContent.create = createShorthandFactory(ListContent, content => ({ content }))

export default ListContent
24 changes: 13 additions & 11 deletions src/elements/List/ListDescription.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,19 @@ import {
childrenUtils,
createShorthandFactory,
customPropTypes,
getElementType,
ElementType,
getUnhandledProps,
META,
withComputedType,
} from '../../lib'

/**
* A list item can contain a description.
*/
function ListDescription(props) {
const InnerListDescription = (props) => {
const { children, className, content } = props
const classes = cx(className, 'description')
const rest = getUnhandledProps(ListDescription, props)
const ElementType = getElementType(ListDescription, props)
const rest = getUnhandledProps(InnerListDescription, props, { passAs: true })

return (
<ElementType {...rest} className={classes}>
Expand All @@ -27,13 +27,7 @@ function ListDescription(props) {
)
}

ListDescription._meta = {
name: 'ListDescription',
parent: 'List',
type: META.TYPES.ELEMENT,
}

ListDescription.propTypes = {
InnerListDescription.propTypes = {
/** An element type to render as (string or function). */
as: customPropTypes.as,

Expand All @@ -47,6 +41,14 @@ ListDescription.propTypes = {
content: customPropTypes.contentShorthand,
}

const ListDescription = withComputedType()(InnerListDescription)

ListDescription._meta = {
name: 'ListDescription',
parent: 'List',
type: META.TYPES.ELEMENT,
}

ListDescription.create = createShorthandFactory(ListDescription, content => ({ content }))

export default ListDescription
Loading

0 comments on commit d117cf6

Please sign in to comment.