Skip to content

Commit 9499d88

Browse files
authored
Merge pull request #83 from nkbt/inputRef
Add inputRef prop to pass as ref to input element
2 parents 686a7b4 + 60d2891 commit 9499d88

File tree

4 files changed

+89
-29
lines changed

4 files changed

+89
-29
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,12 @@ Notification of current value will be sent immediately by hitting `Enter` key. E
132132

133133
Same as `forceNotifyByEnter`, but notification will be sent when focus leaves the input field.
134134

135+
#### `inputRef`: PropTypes.func (default: undefined)
136+
137+
Will pass `ref={inputRef}` to generated input element. We needed to rename `ref` to `inputRef` since `ref` is a special prop in React and cannot be passed to children.
138+
139+
See [./example/Ref.js](./example/Ref.js) for usage example.
140+
135141
#### Arbitrary props will be transferred to rendered `<input>`
136142

137143
```js

example/App.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {Controllable} from './Controllable';
33
import {Customizable} from './Customizable';
44
import {UndoRedo} from './UndoRedo';
55
import {Textarea} from './Textarea';
6+
import {Ref} from './Ref';
67

78

89
export const App = () => (
@@ -27,5 +28,10 @@ export const App = () => (
2728
<h2>Example 4. Debounced Textarea</h2>
2829
<Textarea />
2930
</section>
31+
32+
<section className="section">
33+
<h2>Example 5. Custom ref</h2>
34+
<Ref />
35+
</section>
3036
</div>
3137
);

example/Ref.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import React from 'react';
2+
import {DebounceInput} from '../src';
3+
4+
5+
export class Ref extends React.Component {
6+
state = {
7+
value: '',
8+
key: undefined
9+
};
10+
11+
12+
render() {
13+
const {
14+
value,
15+
key
16+
} = this.state;
17+
18+
return (
19+
<div>
20+
<div className="config">
21+
<label className="label">
22+
<button onClick={() => this.ref.focus()}>Focus, please</button>
23+
</label>
24+
25+
<label className="label">
26+
<button onClick={() => this.ref.blur()}>Blur, please</button>
27+
</label>
28+
</div>
29+
30+
<DebounceInput
31+
inputRef={ref => {
32+
this.ref = ref;
33+
}}
34+
onChange={e => this.setState({value: e.target.value})}
35+
onKeyDown={e => this.setState({key: e.key})} />
36+
<p>Value: {value}</p>
37+
<p>Key pressed: {key}</p>
38+
</div>
39+
40+
);
41+
}
42+
}

src/Component.js

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ export class DebounceInput extends React.PureComponent {
1717
minLength: PropTypes.number,
1818
debounceTimeout: PropTypes.number,
1919
forceNotifyByEnter: PropTypes.bool,
20-
forceNotifyOnBlur: PropTypes.bool
20+
forceNotifyOnBlur: PropTypes.bool,
21+
inputRef: PropTypes.func
2122
};
2223

2324

@@ -30,7 +31,8 @@ export class DebounceInput extends React.PureComponent {
3031
minLength: 0,
3132
debounceTimeout: 100,
3233
forceNotifyByEnter: true,
33-
forceNotifyOnBlur: true
34+
forceNotifyOnBlur: true,
35+
inputRef: undefined
3436
};
3537

3638

@@ -91,6 +93,30 @@ export class DebounceInput extends React.PureComponent {
9193
};
9294

9395

96+
onKeyDown = event => {
97+
const {onKeyDown} = this.props;
98+
99+
if (event.key === 'Enter') {
100+
this.forceNotify(event);
101+
}
102+
// Invoke original onKeyDown if present
103+
if (onKeyDown) {
104+
onKeyDown(event);
105+
}
106+
};
107+
108+
109+
onBlur = event => {
110+
const {onBlur} = this.props;
111+
112+
this.forceNotify(event);
113+
// Invoke original onBlur if present
114+
if (onBlur) {
115+
onBlur(event);
116+
}
117+
};
118+
119+
94120
createNotifier = debounceTimeout => {
95121
if (debounceTimeout < 0) {
96122
this.notify = () => null;
@@ -107,9 +133,7 @@ export class DebounceInput extends React.PureComponent {
107133
debouncedChangeFunc(event);
108134
};
109135

110-
this.flush = () => {
111-
debouncedChangeFunc.flush();
112-
};
136+
this.flush = () => debouncedChangeFunc.flush();
113137

114138
this.cancel = () => {
115139
this.isDebouncing = false;
@@ -157,55 +181,37 @@ export class DebounceInput extends React.PureComponent {
157181
forceNotifyOnBlur,
158182
onKeyDown,
159183
onBlur,
184+
inputRef,
160185
...props
161186
} = this.props;
162187

163188
let maybeOnKeyDown;
164-
165189
if (forceNotifyByEnter) {
166-
maybeOnKeyDown = {
167-
onKeyDown: event => {
168-
if (event.key === 'Enter') {
169-
this.forceNotify(event);
170-
}
171-
// Invoke original onKeyDown if present
172-
if (onKeyDown) {
173-
onKeyDown(event);
174-
}
175-
}
176-
};
190+
maybeOnKeyDown = {onKeyDown: this.onKeyDown};
177191
} else if (onKeyDown) {
178192
maybeOnKeyDown = {onKeyDown};
179193
} else {
180194
maybeOnKeyDown = {};
181195
}
182196

183-
184197
let maybeOnBlur;
185-
186198
if (forceNotifyOnBlur) {
187-
maybeOnBlur = {
188-
onBlur: event => {
189-
this.forceNotify(event);
190-
// Invoke original onBlur if present
191-
if (onBlur) {
192-
onBlur(event);
193-
}
194-
}
195-
};
199+
maybeOnBlur = {onBlur: this.onBlur};
196200
} else if (onBlur) {
197201
maybeOnBlur = {onBlur};
198202
} else {
199203
maybeOnBlur = {};
200204
}
201205

206+
const maybeRef = inputRef ? {ref: inputRef} : {};
202207

203208
return React.createElement(element, {
204209
...props,
205210
onChange: this.onChange,
206211
value: this.state.value,
207212
...maybeOnKeyDown,
208-
...maybeOnBlur
213+
...maybeOnBlur,
214+
...maybeRef
209215
});
210216
}
211217
}

0 commit comments

Comments
 (0)