Skip to content

Commit 022f5e2

Browse files
committed
chore(Modal*|Popup*): use React.forwardRef() (#4261)
1 parent d96b8ef commit 022f5e2

13 files changed

+67
-47
lines changed

src/modules/Modal/ModalActions.js

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import cx from 'clsx'
22
import _ from 'lodash'
33
import PropTypes from 'prop-types'
4-
import React, { Component } from 'react'
4+
import React from 'react'
55

66
import {
77
childrenUtils,
@@ -15,45 +15,45 @@ import Button from '../../elements/Button'
1515
/**
1616
* A modal can contain a row of actions.
1717
*/
18-
export default class ModalActions extends Component {
19-
handleButtonOverrides = (predefinedProps) => ({
20-
onClick: (e, buttonProps) => {
21-
_.invoke(predefinedProps, 'onClick', e, buttonProps)
22-
_.invoke(this.props, 'onActionClick', e, buttonProps)
23-
},
24-
})
18+
const ModalActions = React.forwardRef(function (props, ref) {
19+
const { actions, children, className, content } = props
2520

26-
render() {
27-
const { actions, children, className, content } = this.props
28-
const classes = cx('actions', className)
29-
const rest = getUnhandledProps(ModalActions, this.props)
30-
const ElementType = getElementType(ModalActions, this.props)
31-
32-
if (!childrenUtils.isNil(children)) {
33-
return (
34-
<ElementType {...rest} className={classes}>
35-
{children}
36-
</ElementType>
37-
)
38-
}
39-
if (!childrenUtils.isNil(content)) {
40-
return (
41-
<ElementType {...rest} className={classes}>
42-
{content}
43-
</ElementType>
44-
)
45-
}
21+
const classes = cx('actions', className)
22+
const rest = getUnhandledProps(ModalActions, props)
23+
const ElementType = getElementType(ModalActions, props)
4624

25+
if (!childrenUtils.isNil(children)) {
26+
return (
27+
<ElementType {...rest} className={classes} ref={ref}>
28+
{children}
29+
</ElementType>
30+
)
31+
}
32+
if (!childrenUtils.isNil(content)) {
4733
return (
4834
<ElementType {...rest} className={classes}>
49-
{_.map(actions, (action) =>
50-
Button.create(action, { overrideProps: this.handleButtonOverrides }),
51-
)}
35+
{content}
5236
</ElementType>
5337
)
5438
}
55-
}
5639

40+
return (
41+
<ElementType {...rest} className={classes} ref={ref}>
42+
{_.map(actions, (action) =>
43+
Button.create(action, {
44+
overrideProps: (predefinedProps) => ({
45+
onClick: (e, buttonProps) => {
46+
_.invoke(predefinedProps, 'onClick', e, buttonProps)
47+
_.invoke(props, 'onActionClick', e, buttonProps)
48+
},
49+
}),
50+
}),
51+
)}
52+
</ElementType>
53+
)
54+
})
55+
56+
ModalActions.displayName = 'ModalActions'
5757
ModalActions.propTypes = {
5858
/** An element type to render as (string or function). */
5959
as: PropTypes.elementType,
@@ -80,3 +80,5 @@ ModalActions.propTypes = {
8080
}
8181

8282
ModalActions.create = createShorthandFactory(ModalActions, (actions) => ({ actions }))
83+
84+
export default ModalActions

src/modules/Modal/ModalContent.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414
/**
1515
* A modal can contain content.
1616
*/
17-
function ModalContent(props) {
17+
const ModalContent = React.forwardRef(function (props, ref) {
1818
const { children, className, content, image, scrolling } = props
1919

2020
const classes = cx(
@@ -27,12 +27,13 @@ function ModalContent(props) {
2727
const ElementType = getElementType(ModalContent, props)
2828

2929
return (
30-
<ElementType {...rest} className={classes}>
30+
<ElementType {...rest} className={classes} ref={ref}>
3131
{childrenUtils.isNil(children) ? content : children}
3232
</ElementType>
3333
)
34-
}
34+
})
3535

36+
ModalContent.displayName = 'ModalContent'
3637
ModalContent.propTypes = {
3738
/** An element type to render as (string or function). */
3839
as: PropTypes.elementType,

src/modules/Modal/ModalDescription.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,20 @@ import { childrenUtils, customPropTypes, getElementType, getUnhandledProps } fro
77
/**
88
* A modal can contain a description with one or more paragraphs.
99
*/
10-
function ModalDescription(props) {
10+
const ModalDescription = React.forwardRef(function (props, ref) {
1111
const { children, className, content } = props
1212
const classes = cx('description', className)
1313
const rest = getUnhandledProps(ModalDescription, props)
1414
const ElementType = getElementType(ModalDescription, props)
1515

1616
return (
17-
<ElementType {...rest} className={classes}>
17+
<ElementType {...rest} className={classes} ref={ref}>
1818
{childrenUtils.isNil(children) ? content : children}
1919
</ElementType>
2020
)
21-
}
21+
})
2222

23+
ModalDescription.displayName = 'ModalDescription'
2324
ModalDescription.propTypes = {
2425
/** An element type to render as (string or function). */
2526
as: PropTypes.elementType,

src/modules/Modal/ModalHeader.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,20 @@ import {
1313
/**
1414
* A modal can have a header.
1515
*/
16-
function ModalHeader(props) {
16+
const ModalHeader = React.forwardRef(function (props, ref) {
1717
const { children, className, content } = props
1818
const classes = cx('header', className)
1919
const rest = getUnhandledProps(ModalHeader, props)
2020
const ElementType = getElementType(ModalHeader, props)
2121

2222
return (
23-
<ElementType {...rest} className={classes}>
23+
<ElementType {...rest} className={classes} ref={ref}>
2424
{childrenUtils.isNil(children) ? content : children}
2525
</ElementType>
2626
)
27-
}
27+
})
2828

29+
ModalHeader.displayName = 'ModalHeader'
2930
ModalHeader.propTypes = {
3031
/** An element type to render as (string or function). */
3132
as: PropTypes.elementType,

src/modules/Popup/PopupContent.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,20 @@ import {
1313
/**
1414
* A PopupContent displays the content body of a Popover.
1515
*/
16-
export default function PopupContent(props) {
16+
const PopupContent = React.forwardRef(function (props, ref) {
1717
const { children, className, content } = props
1818
const classes = cx('content', className)
1919
const rest = getUnhandledProps(PopupContent, props)
2020
const ElementType = getElementType(PopupContent, props)
2121

2222
return (
23-
<ElementType {...rest} className={classes}>
23+
<ElementType {...rest} className={classes} ref={ref}>
2424
{childrenUtils.isNil(children) ? content : children}
2525
</ElementType>
2626
)
27-
}
27+
})
2828

29+
PopupContent.displayName = 'PopupContent'
2930
PopupContent.propTypes = {
3031
/** An element type to render as (string or function). */
3132
as: PropTypes.elementType,
@@ -41,3 +42,5 @@ PopupContent.propTypes = {
4142
}
4243

4344
PopupContent.create = createShorthandFactory(PopupContent, (children) => ({ children }))
45+
46+
export default PopupContent

src/modules/Popup/PopupHeader.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,21 @@ import {
1313
/**
1414
* A PopupHeader displays a header in a Popover.
1515
*/
16-
export default function PopupHeader(props) {
16+
const PopupHeader = React.forwardRef(function (props, ref) {
1717
const { children, className, content } = props
18+
1819
const classes = cx('header', className)
1920
const rest = getUnhandledProps(PopupHeader, props)
2021
const ElementType = getElementType(PopupHeader, props)
2122

2223
return (
23-
<ElementType {...rest} className={classes}>
24+
<ElementType {...rest} className={classes} ref={ref}>
2425
{childrenUtils.isNil(children) ? content : children}
2526
</ElementType>
2627
)
27-
}
28+
})
2829

30+
PopupHeader.displayName = 'PopupHeader'
2931
PopupHeader.propTypes = {
3032
/** An element type to render as (string or function). */
3133
as: PropTypes.elementType,
@@ -41,3 +43,5 @@ PopupHeader.propTypes = {
4143
}
4244

4345
PopupHeader.create = createShorthandFactory(PopupHeader, (children) => ({ children }))
46+
47+
export default PopupHeader

test/specs/modules/Modal/ModalActions-test.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import { sandbox } from 'test/utils'
66

77
describe('ModalActions', () => {
88
common.isConformant(ModalActions)
9+
common.forwardsRef(ModalActions)
10+
common.forwardsRef(ModalActions, { requiredProps: { children: <span /> } })
911
common.rendersChildren(ModalActions)
1012

1113
common.implementsCreateMethod(ModalActions)

test/specs/modules/Modal/ModalContent-test.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import * as common from 'test/specs/commonTests'
33

44
describe('ModalContent', () => {
55
common.isConformant(ModalContent)
6+
common.forwardsRef(ModalContent)
67
common.rendersChildren(ModalContent)
78

89
common.implementsCreateMethod(ModalContent)

test/specs/modules/Modal/ModalDescription-test.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@ import * as common from 'test/specs/commonTests'
33

44
describe('ModalDescription', () => {
55
common.isConformant(ModalDescription)
6+
common.forwardsRef(ModalDescription)
67
common.rendersChildren(ModalDescription)
78
})

test/specs/modules/Modal/ModalDimmer-test.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import * as common from 'test/specs/commonTests'
55

66
describe('ModalDimmer', () => {
77
common.isConformant(ModalDimmer)
8+
common.forwardsRef(ModalDimmer)
89
common.hasUIClassName(ModalDimmer)
910
common.rendersChildren(ModalDimmer)
1011

0 commit comments

Comments
 (0)