Skip to content

Commit cc20005

Browse files
authored
chore(Confirm|Checkbox|Embed|Radio|TextArea): use React.forwardRef() (#4262)
1 parent 75d0c8d commit cc20005

File tree

11 files changed

+425
-351
lines changed

11 files changed

+425
-351
lines changed

src/addons/Confirm/Confirm.js

Lines changed: 37 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import _ from 'lodash'
22
import PropTypes from 'prop-types'
3-
import React, { Component } from 'react'
3+
import React from 'react'
44

55
import { customPropTypes, getUnhandledProps } from '../../lib'
66
import Button from '../../elements/Button'
@@ -10,55 +10,56 @@ import Modal from '../../modules/Modal'
1010
* A Confirm modal gives the user a choice to confirm or cancel an action/
1111
* @see Modal
1212
*/
13-
class Confirm extends Component {
14-
handleCancel = (e) => {
15-
_.invoke(this.props, 'onCancel', e, this.props)
13+
const Confirm = React.forwardRef(function (props, ref) {
14+
const { cancelButton, confirmButton, content, header, open, size } = props
15+
const rest = getUnhandledProps(Confirm, props)
16+
17+
const handleCancel = (e) => {
18+
_.invoke(props, 'onCancel', e, props)
1619
}
1720

18-
handleCancelOverrides = (predefinedProps) => ({
21+
const handleCancelOverrides = (predefinedProps) => ({
1922
onClick: (e, buttonProps) => {
2023
_.invoke(predefinedProps, 'onClick', e, buttonProps)
21-
this.handleCancel(e)
24+
handleCancel(e)
2225
},
2326
})
2427

25-
handleConfirmOverrides = (predefinedProps) => ({
28+
const handleConfirmOverrides = (predefinedProps) => ({
2629
onClick: (e, buttonProps) => {
2730
_.invoke(predefinedProps, 'onClick', e, buttonProps)
28-
_.invoke(this.props, 'onConfirm', e, this.props)
31+
_.invoke(props, 'onConfirm', e, props)
2932
},
3033
})
3134

32-
render() {
33-
const { cancelButton, confirmButton, content, header, open, size } = this.props
34-
const rest = getUnhandledProps(Confirm, this.props)
35-
36-
// `open` is auto controlled by the Modal
37-
// It cannot be present (even undefined) with `defaultOpen`
38-
// only apply it if the user provided an open prop
39-
const openProp = {}
40-
if (_.has(this.props, 'open')) openProp.open = open
41-
42-
return (
43-
<Modal {...rest} {...openProp} size={size} onClose={this.handleCancel}>
44-
{Modal.Header.create(header, { autoGenerateKey: false })}
45-
{Modal.Content.create(content, { autoGenerateKey: false })}
46-
<Modal.Actions>
47-
{Button.create(cancelButton, {
48-
autoGenerateKey: false,
49-
overrideProps: this.handleCancelOverrides,
50-
})}
51-
{Button.create(confirmButton, {
52-
autoGenerateKey: false,
53-
defaultProps: { primary: true },
54-
overrideProps: this.handleConfirmOverrides,
55-
})}
56-
</Modal.Actions>
57-
</Modal>
58-
)
35+
// `open` is auto controlled by the Modal
36+
// It cannot be present (even undefined) with `defaultOpen`
37+
// only apply it if the user provided an open prop
38+
const openProp = {}
39+
if (_.has(props, 'open')) {
40+
openProp.open = open
5941
}
60-
}
6142

43+
return (
44+
<Modal {...rest} {...openProp} size={size} onClose={handleCancel} ref={ref}>
45+
{Modal.Header.create(header, { autoGenerateKey: false })}
46+
{Modal.Content.create(content, { autoGenerateKey: false })}
47+
<Modal.Actions>
48+
{Button.create(cancelButton, {
49+
autoGenerateKey: false,
50+
overrideProps: handleCancelOverrides,
51+
})}
52+
{Button.create(confirmButton, {
53+
autoGenerateKey: false,
54+
defaultProps: { primary: true },
55+
overrideProps: handleConfirmOverrides,
56+
})}
57+
</Modal.Actions>
58+
</Modal>
59+
)
60+
})
61+
62+
Confirm.displayName = 'Confirm'
6263
Confirm.propTypes = {
6364
/** The cancel button text. */
6465
cancelButton: customPropTypes.itemShorthand,

src/addons/Radio/Radio.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,19 @@ import Checkbox from '../../modules/Checkbox'
99
* @see Checkbox
1010
* @see Form
1111
*/
12-
function Radio(props) {
12+
const Radio = React.forwardRef(function (props, ref) {
1313
const { slider, toggle, type } = props
14+
1415
const rest = getUnhandledProps(Radio, props)
1516
// const ElementType = getElementType(Radio, props)
1617
// radio, slider, toggle are exclusive
1718
// use an undefined radio if slider or toggle are present
1819
const radio = !(slider || toggle) || undefined
1920

20-
return <Checkbox {...rest} type={type} radio={radio} slider={slider} toggle={toggle} />
21-
}
21+
return <Checkbox {...rest} type={type} radio={radio} slider={slider} toggle={toggle} ref={ref} />
22+
})
2223

24+
Radio.displayName = 'Radio'
2325
Radio.propTypes = {
2426
/** Format to emphasize the current selection state. */
2527
slider: Checkbox.propTypes.slider,

src/addons/TextArea/TextArea.js

Lines changed: 27 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,45 @@
1-
import { Ref } from '@fluentui/react-component-ref'
21
import _ from 'lodash'
32
import PropTypes from 'prop-types'
4-
import React, { Component, createRef } from 'react'
3+
import React from 'react'
54

6-
import { getElementType, getUnhandledProps } from '../../lib'
5+
import { getElementType, getUnhandledProps, useMergedRefs } from '../../lib'
76

87
/**
98
* A TextArea can be used to allow for extended user input.
109
* @see Form
1110
*/
12-
class TextArea extends Component {
13-
ref = createRef()
11+
const TextArea = React.forwardRef(function (props, ref) {
12+
const { rows, value } = props
13+
const elementRef = useMergedRefs(ref, React.useRef())
1414

15-
focus = () => this.ref.current.focus()
15+
const handleChange = (e) => {
16+
const newValue = _.get(e, 'target.value')
1617

17-
handleChange = (e) => {
18-
const value = _.get(e, 'target.value')
19-
20-
_.invoke(this.props, 'onChange', e, { ...this.props, value })
18+
_.invoke(props, 'onChange', e, { ...props, value: newValue })
2119
}
2220

23-
handleInput = (e) => {
24-
const value = _.get(e, 'target.value')
21+
const handleInput = (e) => {
22+
const newValue = _.get(e, 'target.value')
2523

26-
_.invoke(this.props, 'onInput', e, { ...this.props, value })
24+
_.invoke(props, 'onInput', e, { ...props, value: newValue })
2725
}
2826

29-
render() {
30-
const { rows, value } = this.props
31-
const rest = getUnhandledProps(TextArea, this.props)
32-
const ElementType = getElementType(TextArea, this.props)
33-
34-
return (
35-
<Ref innerRef={this.ref}>
36-
<ElementType
37-
{...rest}
38-
onChange={this.handleChange}
39-
onInput={this.handleInput}
40-
rows={rows}
41-
value={value}
42-
/>
43-
</Ref>
44-
)
45-
}
46-
}
47-
27+
const rest = getUnhandledProps(TextArea, props)
28+
const ElementType = getElementType(TextArea, props)
29+
30+
return (
31+
<ElementType
32+
{...rest}
33+
onChange={handleChange}
34+
onInput={handleInput}
35+
ref={elementRef}
36+
rows={rows}
37+
value={value}
38+
/>
39+
)
40+
})
41+
42+
TextArea.displayName = 'TextArea'
4843
TextArea.propTypes = {
4944
/** An element type to render as (string or function). */
5045
as: PropTypes.elementType,

0 commit comments

Comments
 (0)