Reputation: 5599
I want to show a capslock indicator on a password field in a formik form. I need to detect onKeyUp events, is this (detecting keyboard events) possible using formik and the password field component?
Upvotes: 4
Views: 4006
Reputation: 1443
Old, but here's a hook for it using TypeScript:
import { useEffect, useState } from 'react';
type KeyLock = 'CapsLock' | 'NumLock' | 'ScrollLock';
const useKeyLock = (key: KeyLock) => {
const [toggled, setToggled] = useState(false);
useEffect(() => {
const onKeyDown = (event: KeyboardEvent) => setToggled((pToggled) => event.getModifierState?.(key) ?? pToggled);
document.addEventListener('keydown', onKeyDown);
return () => document.removeEventListener('keydown', onKeyDown);
}, [key]);
return toggled;
};
export default useKeyLock;
and it could be used like
const YourForm = () => {
const capsLock = useKeyLock('CapsLock');
return (
<form>
<label>Password</label>
<input type="password" />
{capsLock && <div>Caps Lock Enabled</div>}
</form>
)
}
Upvotes: 5
Reputation: 7536
This doesn't really have anything to do with Formik particularly. You can just use onKeyDown()
like you would on a normal input:
class Login extends React.PureComponent {
state = { warning: false };
/**
* Hide warning when losing focus.
* @param handleBlur Formik blur event.
* @param event Input event.
*/
onBlur(handleBlur, event) {
this.setState({ warning: false });
handleBlur(event);
}
/**
* Detect caps lock being on when typing.
* @param keyEvent On key down event.
*/
onKeyDown = keyEvent => {
if (keyEvent.getModifierState("CapsLock")) {
this.setState({ warning: true });
} else {
this.setState({ warning: false });
}
};
/**
* Show a password field that detects the caps lock key.
* @returns Form with a password field.
*/
render() {
return (
<Formik initialValues={{ password: "" }}>
<Form>
<label htmlFor="password">Password</label>
<Field name="password">
{({ field }) => (
<input
{...field}
id="password"
onBlur={this.onBlur.bind(this, field.handleBlur)}
onKeyDown={this.onKeyDown}
type="password"
/>
)}
</Field>
{this.state.warning && <div>Caps Lock On!</div>}
</Form>
</Formik>
);
}
}
See it working here.
This is a minimal example. I would probably throttle the onKeyDown()
check.
Upvotes: 5