Skip to content

Instantly share code, notes, and snippets.

@msandrini
Created May 14, 2021 09:20
Show Gist options
  • Save msandrini/f87eaeb438d38247ed8960e298c4a0e8 to your computer and use it in GitHub Desktop.
Save msandrini/f87eaeb438d38247ed8960e298c4a0e8 to your computer and use it in GitHub Desktop.
Vue 3 directive with Typescript - focusChangeNotify
import { DirectiveBinding, ObjectDirective } from 'vue'
type FocusableElement = HTMLInputElement | HTMLTextAreaElement
type NotificationCallback = (isNowFocused: boolean) => void
type GenericEventHandler = () => void
interface ExtendedDirective extends ObjectDirective {
handleFocus: GenericEventHandler
handleBlur: GenericEventHandler
}
const focusChangeNotify = {
handleFocus: (() => {}) as GenericEventHandler,
handleBlur: (() => {}) as GenericEventHandler,
mounted(element: FocusableElement, binding: DirectiveBinding) {
const callback = (binding.value as NotificationCallback)
const thisDirective = binding.dir as ExtendedDirective
thisDirective.handleFocus = () => { callback(true) }
thisDirective.handleBlur = () => { callback(false) }
element.addEventListener('focus', thisDirective.handleFocus)
element.addEventListener('blur', thisDirective.handleBlur)
},
beforeUnmount(element: FocusableElement, binding: DirectiveBinding) {
const thisDirective = binding.dir as ExtendedDirective
element.removeEventListener('focus', thisDirective.handleFocus)
element.removeEventListener('blur', thisDirective.handleBlur)
}
}
export default focusChangeNotify
@LiamKarlMitchell
Copy link

LiamKarlMitchell commented Jun 21, 2022

From the above eslint complains about.
Unsafe argument of type any assigned to a parameter of type () => void

el.additionalData.timeout = setTimeout(binding.value, delay);

Casting it seemed to make it happy.

el.additionalData.timeout = setTimeout(binding.value as () => void, delay);

Or perhaps better

const pointerdownEvent = (el: ExtendedHTMLElement, binding: DirectiveBinding<CallbackType>) => {
  const delay = binding.arg ? parseInt(binding.arg) : 500;
  el.additionalData.timeout = setTimeout(binding.value, delay);
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment