Skip to content

Commit b6a00d9

Browse files
authored
feat(prevent-chars): Filter characters on key down (#35)
1 parent 2c18db4 commit b6a00d9

File tree

10 files changed

+80
-56
lines changed

10 files changed

+80
-56
lines changed

.DS_Store

0 Bytes
Binary file not shown.
File renamed without changes.

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ const props = {
8989
| isValid | bool | Returns true if an input element contains valid data. |
9090
| disabled | bool | When present, it specifies that the element should be disabled. |
9191
| autoFocus | bool | Setup autofocus on the first input, `true` by default. |
92+
| filterKeyCodes | array | Filter characters on key down. |
9293

9394
## Compatible with
9495
[`redux-form`](https://github.com/erikras/redux-form) from [erikras](https://github.com/erikras)

example/dist/example.js

Lines changed: 3 additions & 3 deletions
Large diffs are not rendered by default.

example/dist/example.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/ReactCodeInput.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/ReactCodeInput.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@
3030
"coverageThreshold": {
3131
"global": {
3232
"branches": 80,
33-
"functions": 80,
34-
"lines": 80,
35-
"statements": 80
33+
"functions": 100,
34+
"lines": 95,
35+
"statements": 95
3636
}
3737
},
3838
"coveragePathIgnorePatterns": [

src/ReactCodeInput.js

Lines changed: 61 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -13,34 +13,35 @@ class ReactCodeInput extends Component {
1313
constructor(props) {
1414
super(props);
1515

16-
const { value, fields, type, isValid, disabled } = props;
16+
const { value, fields, type, isValid, disabled, filterKeyCodes } = props;
1717

1818
this.state = {
1919
value,
2020
fields,
2121
type,
22-
input: [],
22+
input: [],
2323
isValid,
2424
disabled,
25+
filterKeyCodes,
2526
defaultInputStyle: {
26-
fontFamily: 'monospace',
27+
fontFamily: 'monospace',
2728
MozAppearance: 'textfield',
28-
borderRadius: '6px',
29-
border: '1px solid',
30-
boxShadow: '0px 0px 10px 0px rgba(0,0,0,.10)',
31-
margin: '4px',
32-
paddingLeft: '8px',
33-
width: '36px',
34-
height: '42px',
35-
fontSize: '32px',
36-
boxSizing: 'border-box'
37-
}
29+
borderRadius: '6px',
30+
border: '1px solid',
31+
boxShadow: '0px 0px 10px 0px rgba(0,0,0,.10)',
32+
margin: '4px',
33+
paddingLeft: '8px',
34+
width: '36px',
35+
height: '42px',
36+
fontSize: '32px',
37+
boxSizing: 'border-box',
38+
},
3839
};
3940

4041
for (let i = 0; i < Number(this.state.fields); i += 1) {
4142
if (i < 32) {
4243
const value = this.state.value[i] || '';
43-
this.state.input.push(value)
44+
this.state.input.push(value);
4445
}
4546
}
4647

@@ -51,10 +52,10 @@ class ReactCodeInput extends Component {
5152

5253
componentWillReceiveProps(nextProps) {
5354
this.setState({
54-
isValid: nextProps.isValid,
55-
value: nextProps.value,
56-
disabled: nextProps.disabled,
57-
});
55+
isValid: nextProps.isValid,
56+
value: nextProps.value,
57+
disabled: nextProps.disabled,
58+
});
5859
}
5960

6061
handleBlur(e) {
@@ -103,7 +104,9 @@ class ReactCodeInput extends Component {
103104
return false;
104105
});
105106

106-
const newTarget = this.textInput[e.target.dataset.id < input.length ? Number(e.target.dataset.id) + 1 : e.target.dataset.id];
107+
const newTarget = this.textInput[e.target.dataset.id < input.length
108+
? Number(e.target.dataset.id) + 1
109+
: e.target.dataset.id];
107110

108111
if (newTarget) {
109112
newTarget.focus();
@@ -124,11 +127,20 @@ class ReactCodeInput extends Component {
124127

125128
handleKeyDown(e) {
126129
const target = Number(e.target.dataset.id),
127-
nextTarget = this.textInput[target + 1],
128-
prevTarget = this.textInput[target - 1];
130+
nextTarget = this.textInput[target + 1],
131+
prevTarget = this.textInput[target - 1];
129132

130133
let input, value;
131134

135+
if (this.state.filterKeyCodes.length > 0) {
136+
this.state.filterKeyCodes.map((item) => {
137+
if (item === e.keyCode) {
138+
e.preventDefault();
139+
return true;
140+
}
141+
});
142+
}
143+
132144
switch (e.keyCode) {
133145
case BACKSPACE_KEY:
134146
e.preventDefault();
@@ -183,11 +195,11 @@ class ReactCodeInput extends Component {
183195

184196
render() {
185197
const { className, style = {}, inputStyle = {}, inputStyleInvalid = {}, type, autoFocus } = this.props,
186-
{ disabled, input, isValid, defaultInputStyle } = this.state,
187-
styles = {
188-
container: style,
189-
input: isValid ? inputStyle : inputStyleInvalid,
190-
};
198+
{ disabled, input, isValid, defaultInputStyle } = this.state,
199+
styles = {
200+
container: style,
201+
input: isValid ? inputStyle : inputStyleInvalid,
202+
};
191203

192204
Object.assign(styles.container, {
193205
display: 'inline-block',
@@ -249,35 +261,37 @@ class ReactCodeInput extends Component {
249261
);
250262
})}
251263
</div>
252-
)
264+
);
253265
}
254266
}
255267

256268
ReactCodeInput.defaultProps = {
257-
autoFocus: true,
258-
isValid: true,
259-
disabled: false,
260-
fields: 4,
261-
value: '',
262-
type: 'text',
269+
autoFocus: true,
270+
isValid: true,
271+
disabled: false,
272+
fields: 4,
273+
value: '',
274+
type: 'text',
275+
filterKeyCodes: [189, 190],
263276
};
264277

265278
ReactCodeInput.propTypes = {
266-
options: PropTypes.object,
267-
type: PropTypes.oneOf(['text', 'number', 'password', 'tel']),
268-
fields: PropTypes.number,
269-
value: PropTypes.string,
270-
onChange: PropTypes.func,
271-
name: PropTypes.string,
272-
touch: PropTypes.func,
273-
untouch: PropTypes.func,
274-
className: PropTypes.string,
275-
isValid: PropTypes.bool,
276-
disabled: PropTypes.bool,
277-
style: PropTypes.object,
278-
inputStyle: PropTypes.object,
279+
options: PropTypes.object,
280+
type: PropTypes.oneOf(['text', 'number', 'password', 'tel']),
281+
fields: PropTypes.number,
282+
value: PropTypes.string,
283+
onChange: PropTypes.func,
284+
name: PropTypes.string,
285+
touch: PropTypes.func,
286+
untouch: PropTypes.func,
287+
className: PropTypes.string,
288+
isValid: PropTypes.bool,
289+
disabled: PropTypes.bool,
290+
style: PropTypes.object,
291+
inputStyle: PropTypes.object,
279292
inputStyleInvalid: PropTypes.object,
280-
autoFocus: PropTypes.bool,
293+
autoFocus: PropTypes.bool,
294+
filterKeyCodes: PropTypes.array,
281295
};
282296

283297
export default ReactCodeInput;

0 commit comments

Comments
 (0)