Skip to content
This repository has been archived by the owner on Mar 7, 2023. It is now read-only.

Commit

Permalink
feat(input): allow refs for input components (#235)
Browse files Browse the repository at this point in the history
  • Loading branch information
Méril authored Jan 21, 2019
1 parent 921c88d commit 4b44c8c
Show file tree
Hide file tree
Showing 16 changed files with 8,302 additions and 7,520 deletions.
2 changes: 1 addition & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ settings:
onlyFilesWithFlowAnnotation: true
react:
version: 16.7.0
flowVersion: 0.90.0
flowVersion: 0.91.0

rules:
react/sort-comp:
Expand Down
2 changes: 1 addition & 1 deletion .flowconfig
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ sketchy-null
sketchy-number

[version]
^0.90.0
^0.91.0
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@
"enzyme": "3.8.0",
"enzyme-adapter-react-16": "1.7.1",
"enzyme-to-json": "3.3.5",
"eslint": "5.12.0",
"eslint-config-prettier": "3.4.0",
"eslint": "5.12.1",
"eslint-config-prettier": "3.6.0",
"eslint-config-standard": "12.0.0",
"eslint-loader": "2.1.1",
"eslint-plugin-babel": "5.3.0",
Expand All @@ -86,23 +86,23 @@
"eslint-plugin-node": "8.0.1",
"eslint-plugin-prettier": "3.0.1",
"eslint-plugin-promise": "4.0.1",
"eslint-plugin-react": "7.12.3",
"eslint-plugin-react": "7.12.4",
"eslint-plugin-standard": "4.0.0",
"flow-bin": "0.90.0",
"flow-bin": "0.91.0",
"flow-copy-source": "2.0.2",
"flow-coverage-report": "0.6.1",
"husky": "1.3.1",
"jest": "23.6.0",
"jest-styled-components": "6.3.1",
"lint-staged": "8.1.0",
"prettier": "1.15.3",
"prettier": "1.16.0",
"prop-types": "15.6.2",
"react": "16.7.0",
"react-dom": "16.7.0",
"rimraf": "2.6.3",
"standard": "12.0.1",
"styled-components": "4.1.3",
"stylelint": "9.10.0",
"stylelint": "9.10.1",
"stylelint-config-recommended": "2.1.0",
"stylelint-config-standard": "18.2.0",
"stylelint-config-styled-components": "0.1.1",
Expand Down
21 changes: 18 additions & 3 deletions src/Atoms/Inputs/Checkbox.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,26 @@ export const CheckboxLabel = styled.label`
}
`

const Checkbox = ({ className, input, ...rest }: PropsType) => (
const Checkbox = ({
className,
forwardRef: ref,
input,
...rest
}: PropsType) => (
<Wrapper className={className}>
<Input {...input} {...rest} id={toId(rest.name)} type="checkbox" />
<Input
{...input}
{...rest}
id={toId(rest.name)}
ref={ref}
type="checkbox"
/>
<CheckboxLabel htmlFor={toId(rest.name)}>{rest.label}</CheckboxLabel>
</Wrapper>
)

export default Checkbox
type RefPropsType = { ...PropsType }

const CheckboxWithRef = (props, ref) => <Checkbox {...props} forwardRef={ref} />

export default React.forwardRef<RefPropsType, _>(CheckboxWithRef)
14 changes: 10 additions & 4 deletions src/Atoms/Inputs/Input.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export type PropsType = {
+disabled?: boolean,
+e2e?: string,
+error?: string,
+forwardRef?: React.ElementRef<*>,
+input?: {},
+label?: string,
+name?: string,
Expand Down Expand Up @@ -109,8 +110,9 @@ export const InputLabel = styled.label`
props.disabled === true ? 'cursor: not-allowed' : ''};
`

const Input = ({
export const Input = ({
className = '',
forwardRef: ref,
input,
type,
renderSuffix,
Expand Down Expand Up @@ -141,15 +143,15 @@ const Input = ({
hasLabel && hasError ? ' - ' : ''
}${rest.error || ''}`}
</InputLabel>
<InputWrapper {...input} {...rest} type={type} />
<InputWrapper {...input} {...rest} ref={ref} type={type} />
{renderSuffix && renderSuffix(rest.disabled)}
</Container>
)
}

return (
<Container className={className} width={rest.width}>
<InputWrapper {...input} {...rest} type={type} />
<InputWrapper {...input} {...rest} ref={ref} type={type} />
{renderSuffix && renderSuffix(rest.disabled)}
</Container>
)
Expand Down Expand Up @@ -184,4 +186,8 @@ Input.defaultProps = {
width: '100%',
}

export default Input
type RefPropsType = { ...PropsType }

const InputWithRef = (props, ref) => <Input {...props} forwardRef={ref} />

export default React.forwardRef<RefPropsType, _>(InputWithRef)
26 changes: 25 additions & 1 deletion src/Atoms/Inputs/Input.spec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { mount } from 'enzyme'
import React from 'react'
import { mountWithTheme } from '../../Utils/testHelper'

import { mountWithTheme } from '../../Utils/testHelper'
import Input from './Input'

describe('Input', () => {
Expand Down Expand Up @@ -63,4 +64,27 @@ describe('Input', () => {

expect(tree.find(Input)).toMatchSnapshot()
})

it('should accept ref', () => {
class MyComponent extends React.Component {
constructor(props) {
super(props)
this.myRef = React.createRef()
this.focus = this.focus.bind(this)
}

focus() {
this.myRef.current.focus()
}

render() {
return <Input id="TestRef" ref={this.myRef} />
}
}
const wrapper = mount(<MyComponent />)

expect(document.activeElement.type).toBeUndefined()
wrapper.instance().focus()
expect(document.activeElement.id).toEqual('TestRef')
})
})
11 changes: 8 additions & 3 deletions src/Atoms/Inputs/Password.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as React from 'react'
import styled from 'styled-components'

import { fontSize, theme } from '../../Tools/interpolation'
import Input, { type PropsType, type HtmlInputType } from './Input'
import { Input, type PropsType, type HtmlInputType } from './Input'
import { FarEye, FarEyeSlash } from '../Icons'

const Switch = styled.span`
Expand Down Expand Up @@ -59,16 +59,21 @@ class Password extends React.Component<PropsType, StateType> {

render() {
const { type } = this.state
const { renderSuffix } = this.props
const { forwardRef: ref, renderSuffix } = this.props

return (
<PasswordInput
{...this.props}
ref={ref}
renderSuffix={renderSuffix || this.renderToggle}
type={type}
/>
)
}
}

export default Password
type RefPropsType = { ...PropsType }

const PasswordWithRef = (props, ref) => <Password {...props} forwardRef={ref} />

export default React.forwardRef<RefPropsType, _>(PasswordWithRef)
11 changes: 8 additions & 3 deletions src/Atoms/Inputs/Radio.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const Input = styled.input.attrs(injectE2E)`
visibility: visible;
white-space: nowrap;
width: 1px;
user-select: none;
&:focus ~ label ${RadioButton} {
box-shadow: 0 0 0 2px ${theme('inputActiveColor')};
Expand Down Expand Up @@ -69,14 +70,18 @@ export const RadioLabel = styled.label`
font-size: ${fontSize('md')};
`

const Radio = ({ className, input, ...rest }: PropsType) => (
const Radio = ({ className, forwardRef: ref, input, ...rest }: PropsType) => (
<Wrapper className={className}>
<Input {...input} {...rest} id={toId(rest.value)} type="radio" />
<Input {...input} {...rest} id={toId(rest.value)} ref={ref} type="radio" />
<RadioLabel htmlFor={toId(rest.value)}>
<RadioButton />
{rest.label}
</RadioLabel>
</Wrapper>
)

export default Radio
type RefPropsType = { ...PropsType }

const RadioWithRef = (props, ref) => <Radio {...props} forwardRef={ref} />

export default React.forwardRef<RefPropsType, _>(RadioWithRef)
10 changes: 7 additions & 3 deletions src/Atoms/Inputs/TextArea.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ const Wrapper = styled.textarea.attrs(injectE2E)`
}
`

const TextArea = ({ input, ...rest }: PropsType) => {
const TextArea = ({ forwardRef: ref, input, ...rest }: PropsType) => {
const hasLabel = rest.label != null
const hasError = rest.error != null

Expand All @@ -74,7 +74,7 @@ const TextArea = ({ input, ...rest }: PropsType) => {
hasLabel && hasError ? ' - ' : ''
}${rest.error || ''}`}
</InputLabel>
<Wrapper {...input} {...rest} />
<Wrapper {...input} {...rest} ref={ref} />
</Container>
)
}
Expand All @@ -99,4 +99,8 @@ TextArea.defaultProps = {
width: '100%',
}

export default TextArea
type RefPropsType = { ...PropsType }

const TextAreaWithRef = (props, ref) => <TextArea {...props} forwardRef={ref} />

export default React.forwardRef<RefPropsType, _>(TextAreaWithRef)
Loading

0 comments on commit 4b44c8c

Please sign in to comment.