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?
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.
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>
)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With