Skip to content

Commit

Permalink
Merge pull request #440 from SpareBank1/231-use-forwardRef-take-two
Browse files Browse the repository at this point in the history
feat(ffe-form-react): Add support for forwarding refs
  • Loading branch information
selbekk authored Oct 4, 2018
2 parents e4aa6f2 + 998af6c commit 784fa13
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 20 deletions.
2 changes: 1 addition & 1 deletion packages/ffe-form-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"peerDependencies": {
"@sb1/ffe-core": "^12.0.0 || ^13.0.0",
"@sb1/ffe-form": "^9.0.0",
"react": "^16.2.0"
"react": "^16.3.0"
},
"publishConfig": {
"access": "public"
Expand Down
6 changes: 4 additions & 2 deletions packages/ffe-form-react/src/Input.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import React from 'react';
import { bool, string } from 'prop-types';
import classNames from 'classnames';

const Input = ({ className, inline, textLike, ...rest }) => {
const Input = React.forwardRef((props, ref) => {
const { className, inline, textLike, ...rest } = props;
return (
<input
className={classNames(
Expand All @@ -11,10 +12,11 @@ const Input = ({ className, inline, textLike, ...rest }) => {
{ 'ffe-input-field--text-like': textLike },
className,
)}
ref={ref}
{...rest}
/>
);
};
});

Input.propTypes = {
className: string,
Expand Down
44 changes: 40 additions & 4 deletions packages/ffe-form-react/src/Input.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Vi har tre varianter av inputfelt:
2. inline
3. text-like

_Standard_ og _inline_ er mest relevant for utviklere. De ser helt like ut, men opprører seg annerledes i samspillet
_Standard_ og _inline_ er mest relevant for utviklere. De ser helt like ut, men oppfører seg annerledes i samspillet
med andre elementer på siden, for eksempel [tooltip](#tooltip).

```js
Expand All @@ -15,7 +15,7 @@ const { Input } = require('.');
<React.Fragment>
<Label htmlFor="input-first-name">Fornavn</Label>
<Input id="input-first-name" />
</React.Fragment>
</React.Fragment>;
```

_Text-like_-varianten er designet for å kunne brukes som en del av en setning med et minimum av ramme rundt. Det er opp til en utvikler å sette bredden på dette elementet, siden det vil variere fra gang til gang hva man ønsker.
Expand All @@ -24,10 +24,46 @@ _Text-like_-varianten er designet for å kunne brukes som en del av en setning m
const { Input } = require('.');

<p className="ffe-body-paragraph">
Jeg er <Input
Jeg er{' '}
<Input
aria-label="Skriv inn alder"
style={{ width: '47px' }}
textLike={true}
/> år gammel
/>{' '}
år gammel
</p>;
```

## Styr fokus med `ref`

Du kan få en referanse til input-feltet ved å sende inn en `ref`-prop. Brukes typisk til å fokusere et felt programmatisk.

```js
const { Input } = require('.');
const { ButtonGroup, PrimaryButton } = require('../../ffe-buttons-react');

class Example extends React.Component {
constructor() {
super();
this.inputRef = React.createRef();
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.inputRef.current.focus();
}
render() {
return (
<React.Fragment>
<Input ref={this.inputRef} placeholder="Trykk på knappen" />
<ButtonGroup>
<PrimaryButton onClick={this.handleClick}>
Klikk for å fokusere input
</PrimaryButton>
</ButtonGroup>
</React.Fragment>
);
}
}

<Example />;
```
15 changes: 8 additions & 7 deletions packages/ffe-form-react/src/InputGroup.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ describe('<InputGroup>', () => {

it('renders the given child', () => {
const wrapper = getWrapper();
expect(wrapper.find('Input')).toHaveLength(1);
expect(wrapper.find(Input)).toHaveLength(1);
});

it('renders a Label if a string passed from the label prop', () => {
Expand All @@ -37,7 +37,7 @@ describe('<InputGroup>', () => {
it('renders a Label with htmlFor set to the same value of the children id', () => {
const wrapper = getWrapper();

const inputId = wrapper.find('Input').prop('id');
const inputId = wrapper.find(Input).prop('id');
expect(wrapper.find('Label').prop('htmlFor')).toBe(inputId);
});

Expand All @@ -53,7 +53,7 @@ describe('<InputGroup>', () => {
expect(wrapper.find('ErrorFieldMessage').prop('children')).toBe(
'such error',
);
expect(wrapper.find('Input').prop('aria-invalid')).toBe('true');
expect(wrapper.find(Input).prop('aria-invalid')).toBe('true');
});

it('renders a Label component if passed a label prop', () => {
Expand All @@ -80,7 +80,7 @@ describe('<InputGroup>', () => {
expect(wrapper.find('ErrorFieldMessage').prop('children')).toBe(
'Some error',
);
expect(wrapper.find('Input').prop('aria-invalid')).toBe('true');
expect(wrapper.find(Input).prop('aria-invalid')).toBe('true');
});

it('renders a SuccessFieldMessage if passed as fieldMessage prop', () => {
Expand All @@ -94,7 +94,7 @@ describe('<InputGroup>', () => {
expect(wrapper.find('SuccessFieldMessage').prop('children')).toBe(
'Some success',
);
expect(wrapper.find('Input').prop('aria-invalid')).toBe('false');
expect(wrapper.find(Input).prop('aria-invalid')).toBe('false');
});

it('throws error when receiving multiple children', () => {
Expand Down Expand Up @@ -146,8 +146,9 @@ describe('<InputGroup>', () => {
</div>
),
});
expect(wrapper.find('Input').prop('id')).toHaveLength(42);
expect(wrapper.find('Input').prop('aria-invalid')).toBe('false');

expect(wrapper.find(Input).prop('id')).toHaveLength(42);
expect(wrapper.find(Input).prop('aria-invalid')).toBe('false');
});

it('renders a static tooltip if description is set', () => {
Expand Down
11 changes: 8 additions & 3 deletions packages/ffe-form-react/src/TextArea.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@ import React from 'react';
import { string } from 'prop-types';
import classNames from 'classnames';

const TextArea = ({ className, ...rest }) => {
const TextArea = React.forwardRef((props, ref) => {
const { className, ...rest } = props;
return (
<textarea className={classNames('ffe-textarea', className)} {...rest} />
<textarea
className={classNames('ffe-textarea', className)}
ref={ref}
{...rest}
/>
);
};
});

TextArea.propTypes = {
className: string,
Expand Down
41 changes: 38 additions & 3 deletions packages/ffe-form-react/src/TextArea.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,47 @@
```js
<React.Fragment>
<Label htmlFor="textarea-example">
Beskriv skaden
</Label>
<Label htmlFor="textarea-example">Beskriv skaden</Label>
<TextArea
defaultValue="Dette er et tekstfelt for lengre tekster."
id="textarea-example"
rows="8"
/>
</React.Fragment>
```

## Styr fokus med `ref`

Du kan få en referanse til textarea-feltet ved å sende inn en `ref`-prop. Brukes typisk til å fokusere et felt programmatisk.

```js
const { TextArea } = require('.');
const { ButtonGroup, PrimaryButton } = require('../../ffe-buttons-react');

class Example extends React.Component {
constructor() {
super();
this.inputRef = React.createRef();
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.inputRef.current.focus();
}
render() {
return (
<React.Fragment>
<TextArea
ref={this.inputRef}
placeholder="Trykk på knappen for fokus"
/>
<ButtonGroup>
<PrimaryButton onClick={this.handleClick}>
Klikk for å fokusere input
</PrimaryButton>
</ButtonGroup>
</React.Fragment>
);
}
}

<Example />;
```

0 comments on commit 784fa13

Please sign in to comment.