SolidJSS
SolidJSโ€ข3y agoโ€ข
1 reply
calvinandhobbes

How to extend native events

I have a CurrencyManager which handles when the user inputs a number and converts it to a currency in a input field and manages the cursor position. I'd like to add the unmasked and masked value from the manager to all of the events on the input field so end users have access to it. Maybe I'm overthinking the approach but right now I have a curried wrapper function that takes a function and returns a function that receives its native event and calls the original function with the data added to it.

type CurrencyManager = () => {maskedValue: string, unmaskedValue: string}

type CurrencyEvent = Event & unmaskedVaalue:string & maskedValue: string

interface CurrencyInputProps extends HTMLInputElement {
  onInput: (e:CurrencyEvent) => void;
  //other event handlers
}

const CurrencyInput: Component<CurrencyInputProps> = (props) => {
let inputRef: HTMLInputElement;
let manager: CurrencyManger;
onMount(//initalize manager with input ref)
const wrapperFn = (fn:any) => (e:Event) => {
  const event = e as CurrencyEvent
  event.maskedValue = manager.maskedValue
  event.unmaskedValue = manager.unmaskedValue
  fn(event)
}
const wrappedOnInput = createMemo(()=>wrapperFn(props.onInput))

return <input ref={inputRef} onInput={wrappedOnInput()}/>
}


This all works, but it's making forwarding the ref to higher level components for them to manage the value nearly impossible.

It's also annoying to have to do this for the 10+ types of input event handlers.

Is there a cleaner way to implement this?

Maybe having the currency manager intercept the input element's prototype with a proxy so I could do something like e.currentTarget.unmaskedValue and inputRef.disconnect() but I'm not sure how to do that and I know that's usually discouraged because of unexpected behavior/compatibility issues.
Was this page helpful?