Skip to content

Commit

Permalink
chore(Feed): use React.forwardRef() (#4244)
Browse files Browse the repository at this point in the history
  • Loading branch information
layershifter committed Dec 13, 2022
1 parent 269e175 commit c4cf315
Show file tree
Hide file tree
Showing 21 changed files with 79 additions and 37 deletions.
10 changes: 6 additions & 4 deletions src/views/Feed/Feed.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import FeedUser from './FeedUser'
/**
* A feed presents user activity chronologically.
*/
function Feed(props) {
const Feed = React.forwardRef(function (props, ref) {
const { children, className, events, size } = props

const classes = cx('ui', size, 'feed', className)
Expand All @@ -26,7 +26,7 @@ function Feed(props) {

if (!childrenUtils.isNil(children)) {
return (
<ElementType {...rest} className={classes}>
<ElementType {...rest} className={classes} ref={ref}>
{children}
</ElementType>
)
Expand All @@ -36,16 +36,18 @@ function Feed(props) {
const { childKey, date, meta, summary, ...eventData } = eventProps
const finalKey = childKey ?? [date, meta, summary].join('-')

// TODO: use .create() factory
return <FeedEvent date={date} key={finalKey} meta={meta} summary={summary} {...eventData} />
})

return (
<ElementType {...rest} className={classes}>
<ElementType {...rest} className={classes} ref={ref}>
{eventElements}
</ElementType>
)
}
})

Feed.displayName = 'Feed'
Feed.propTypes = {
/** An element type to render as (string or function). */
as: PropTypes.elementType,
Expand Down
9 changes: 5 additions & 4 deletions src/views/Feed/FeedContent.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import FeedExtra from './FeedExtra'
import FeedMeta from './FeedMeta'
import FeedSummary from './FeedSummary'

function FeedContent(props) {
const FeedContent = React.forwardRef(function (props, ref) {
const { children, className, content, extraImages, extraText, date, meta, summary } = props

const classes = cx('content', className)
Expand All @@ -23,14 +23,14 @@ function FeedContent(props) {

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

return (
<ElementType {...rest} className={classes}>
<ElementType {...rest} className={classes} ref={ref}>
{createShorthand(FeedDate, (val) => ({ content: val }), date, { autoGenerateKey: false })}
{createShorthand(FeedSummary, (val) => ({ content: val }), summary, {
autoGenerateKey: false,
Expand All @@ -45,8 +45,9 @@ function FeedContent(props) {
{createShorthand(FeedMeta, (val) => ({ content: val }), meta, { autoGenerateKey: false })}
</ElementType>
)
}
})

FeedContent.displayName = 'FeedContent'
FeedContent.propTypes = {
/** An element type to render as (string or function). */
as: PropTypes.elementType,
Expand Down
7 changes: 4 additions & 3 deletions src/views/Feed/FeedDate.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,20 @@ import { childrenUtils, customPropTypes, getElementType, getUnhandledProps } fro
/**
* An event or an event summary can contain a date.
*/
function FeedDate(props) {
const FeedDate = React.forwardRef(function (props, ref) {
const { children, className, content } = props
const classes = cx('date', className)
const rest = getUnhandledProps(FeedDate, props)
const ElementType = getElementType(FeedDate, props)

return (
<ElementType {...rest} className={classes}>
<ElementType {...rest} className={classes} ref={ref}>
{childrenUtils.isNil(children) ? content : children}
</ElementType>
)
}
})

FeedDate.displayName = 'FeedDate'
FeedDate.propTypes = {
/** An element type to render as (string or function). */
as: PropTypes.elementType,
Expand Down
7 changes: 4 additions & 3 deletions src/views/Feed/FeedEvent.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import FeedLabel from './FeedLabel'
/**
* A feed contains an event.
*/
function FeedEvent(props) {
const FeedEvent = React.forwardRef(function (props, ref) {
const {
content,
children,
Expand All @@ -31,15 +31,16 @@ function FeedEvent(props) {
const contentProps = { content, date, extraImages, extraText, meta, summary }

return (
<ElementType {...rest} className={classes}>
<ElementType {...rest} className={classes} ref={ref}>
{createShorthand(FeedLabel, (val) => ({ icon: val }), icon, { autoGenerateKey: false })}
{createShorthand(FeedLabel, (val) => ({ image: val }), image, { autoGenerateKey: false })}
{hasContentProp && <FeedContent {...contentProps} />}
{children}
</ElementType>
)
}
})

FeedEvent.displayName = 'FeedEvent'
FeedEvent.propTypes = {
/** An element type to render as (string or function). */
as: PropTypes.elementType,
Expand Down
9 changes: 5 additions & 4 deletions src/views/Feed/FeedExtra.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
/**
* A feed can contain an extra content.
*/
function FeedExtra(props) {
const FeedExtra = React.forwardRef(function (props, ref) {
const { children, className, content, images, text } = props

const classes = cx(
Expand All @@ -29,7 +29,7 @@ function FeedExtra(props) {

if (!childrenUtils.isNil(children)) {
return (
<ElementType {...rest} className={classes}>
<ElementType {...rest} className={classes} ref={ref}>
{children}
</ElementType>
)
Expand All @@ -42,13 +42,14 @@ function FeedExtra(props) {
})

return (
<ElementType {...rest} className={classes}>
<ElementType {...rest} className={classes} ref={ref}>
{content}
{imageElements}
</ElementType>
)
}
})

FeedExtra.displayName = 'FeedExtra'
FeedExtra.propTypes = {
/** An element type to render as (string or function). */
as: PropTypes.elementType,
Expand Down
9 changes: 5 additions & 4 deletions src/views/Feed/FeedLabel.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import Icon from '../../elements/Icon'
/**
* An event can contain an image or icon label.
*/
function FeedLabel(props) {
const FeedLabel = React.forwardRef(function (props, ref) {
const { children, className, content, icon, image } = props

const classes = cx('label', className)
Expand All @@ -23,21 +23,22 @@ function FeedLabel(props) {

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

return (
<ElementType {...rest} className={classes}>
<ElementType {...rest} className={classes} ref={ref}>
{content}
{Icon.create(icon, { autoGenerateKey: false })}
{createHTMLImage(image)}
</ElementType>
)
}
})

FeedLabel.displayName = 'FeedLabel'
FeedLabel.propTypes = {
/** An element type to render as (string or function). */
as: PropTypes.elementType,
Expand Down
9 changes: 5 additions & 4 deletions src/views/Feed/FeedLike.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import Icon from '../../elements/Icon'
/**
* A feed can contain a like element.
*/
function FeedLike(props) {
const FeedLike = React.forwardRef(function (props, ref) {
const { children, className, content, icon } = props

const classes = cx('like', className)
Expand All @@ -17,24 +17,25 @@ function FeedLike(props) {

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

return (
<ElementType {...rest} className={classes}>
<ElementType {...rest} className={classes} ref={ref}>
{Icon.create(icon, { autoGenerateKey: false })}
{content}
</ElementType>
)
}
})

FeedLike.defaultProps = {
as: 'a',
}

FeedLike.displayName = 'FeedLike'
FeedLike.propTypes = {
/** An element type to render as (string or function). */
as: PropTypes.elementType,
Expand Down
9 changes: 5 additions & 4 deletions src/views/Feed/FeedMeta.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import FeedLike from './FeedLike'
/**
* A feed can contain a meta.
*/
function FeedMeta(props) {
const FeedMeta = React.forwardRef(function (props, ref) {
const { children, className, content, like } = props

const classes = cx('meta', className)
Expand All @@ -23,20 +23,21 @@ function FeedMeta(props) {

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

return (
<ElementType {...rest} className={classes}>
<ElementType {...rest} className={classes} ref={ref}>
{createShorthand(FeedLike, (val) => ({ content: val }), like, { autoGenerateKey: false })}
{content}
</ElementType>
)
}
})

FeedMeta.displayName = 'FeedMeta'
FeedMeta.propTypes = {
/** An element type to render as (string or function). */
as: PropTypes.elementType,
Expand Down
9 changes: 5 additions & 4 deletions src/views/Feed/FeedSummary.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import FeedUser from './FeedUser'
/**
* A feed can contain a summary.
*/
function FeedSummary(props) {
const FeedSummary = React.forwardRef(function (props, ref) {
const { children, className, content, date, user } = props

const classes = cx('summary', className)
Expand All @@ -24,14 +24,14 @@ function FeedSummary(props) {

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

return (
<ElementType {...rest} className={classes}>
<ElementType {...rest} className={classes} ref={ref}>
{createShorthand(FeedUser, (val) => ({ content: val }), user, { autoGenerateKey: false })}
{/*
Content styles require wrapping whitespace
Expand All @@ -43,8 +43,9 @@ function FeedSummary(props) {
{createShorthand(FeedDate, (val) => ({ content: val }), date, { autoGenerateKey: false })}
</ElementType>
)
}
})

FeedSummary.displayName = 'FeedSummary'
FeedSummary.propTypes = {
/** An element type to render as (string or function). */
as: PropTypes.elementType,
Expand Down
7 changes: 4 additions & 3 deletions src/views/Feed/FeedUser.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,20 @@ import { childrenUtils, customPropTypes, getElementType, getUnhandledProps } fro
/**
* A feed can contain a user element.
*/
function FeedUser(props) {
const FeedUser = React.forwardRef(function (props, ref) {
const { children, className, content } = props
const classes = cx('user', className)
const rest = getUnhandledProps(FeedUser, props)
const ElementType = getElementType(FeedUser, props)

return (
<ElementType {...rest} className={classes}>
<ElementType {...rest} className={classes} ref={ref}>
{childrenUtils.isNil(children) ? content : children}
</ElementType>
)
}
})

FeedUser.displayName = 'FeedUser'
FeedUser.propTypes = {
/** An element type to render as (string or function). */
as: PropTypes.elementType,
Expand Down
8 changes: 8 additions & 0 deletions test/specs/views/Card/Card-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ describe('Card', () => {

wrapper.should.have.tagName('a')
})

it('is called with (e, data) when clicked', () => {
const onClick = sandbox.spy()
mount(<Card onClick={onClick} />).simulate('click')

onClick.should.have.been.calledOnce()
onClick.should.have.been.calledWithMatch({ type: 'click' }, { onClick })
})
})

describe('extra', () => {
Expand Down
2 changes: 2 additions & 0 deletions test/specs/views/Feed/Feed-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import * as common from 'test/specs/commonTests'

describe('Feed', () => {
common.isConformant(Feed)
common.forwardsRef(Feed)
common.forwardsRef(Feed, { requiredProps: { children: <span /> } })
common.hasUIClassName(Feed)
common.rendersChildren(Feed, {
rendersContent: false,
Expand Down
4 changes: 4 additions & 0 deletions test/specs/views/Feed/FeedContent-test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import * as React from 'react'

import FeedContent from 'src/views/Feed/FeedContent'
import FeedDate from 'src/views/Feed/FeedDate'
import FeedSummary from 'src/views/Feed/FeedSummary'
Expand All @@ -7,6 +9,8 @@ import * as common from 'test/specs/commonTests'

describe('FeedContent', () => {
common.isConformant(FeedContent)
common.forwardsRef(FeedContent)
common.forwardsRef(FeedContent, { requiredProps: { children: <span /> } })
common.rendersChildren(FeedContent)

common.implementsShorthandProp(FeedContent, {
Expand Down
1 change: 1 addition & 0 deletions test/specs/views/Feed/FeedDate-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ import * as common from 'test/specs/commonTests'

describe('FeedDate', () => {
common.isConformant(FeedDate)
common.forwardsRef(FeedDate)
common.rendersChildren(FeedDate)
})
1 change: 1 addition & 0 deletions test/specs/views/Feed/FeedEvent-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import * as common from 'test/specs/commonTests'

describe('FeedEvent', () => {
common.isConformant(FeedEvent)
common.forwardsRef(FeedEvent)
common.rendersChildren(FeedEvent, {
rendersContent: false,
})
Expand Down
2 changes: 2 additions & 0 deletions test/specs/views/Feed/FeedExtra-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import * as common from 'test/specs/commonTests'

describe('FeedExtra', () => {
common.isConformant(FeedExtra)
common.forwardsRef(FeedExtra)
common.forwardsRef(FeedExtra, { requiredProps: { children: <span /> } })
common.rendersChildren(FeedExtra)

common.propKeyOnlyToClassName(FeedExtra, 'images')
Expand Down
Loading

0 comments on commit c4cf315

Please sign in to comment.