uNmAnNeR / imaskjs

vanilla javascript input mask
https://imask.js.org
MIT License
4.94k stars 257 forks source link

React plugin #5

Closed uNmAnNeR closed 6 years ago

uNmAnNeR commented 6 years ago

implement react wrapper

yordis commented 6 years ago

@uNmAnNeR is there any timeline for this one?

yordis commented 6 years ago

@uNmAnNeR what are your thoughts in how the component API look like? Right now I am using it and creating something really basic but I would like to have your inputs and help me with some questions I have.

Please check the comments.

import IMask from 'imask'

const componentName = component => component.displayName || component.name || 'Component'

export const iMaskEnhance = ComposedComponent => {
  return class iMask extends PureComponent {
    static displayName = `iMask(${ componentName(ComposedComponent) })`

    componentWillUpdate() {
      // @TODO find what this means also updates UI
      // @TODO update the options
      // check if it is safe to update with the same props
      // or if I have to do some checking
      // this.iMask.updateOptions(this.props.iMask || {})
    }
    //@TODO when would I use this?
    //@TODO what updating UI means?
    // masked.reset(); // UI will NOT be updated

    componentDidMount() {
      this.iMask = new IMask(this.element, this.props.iMask || {})
      const log = () => {
        console.log('onAccept', this.iMask.value)
        console.log('onComplete', this.iMask.unmaskedValue)
      }

      // @TODO use this vs onChange from the input
      this.iMask.on('accept', log)
      this.iMask.on('complete', () => {
        console.log(this.iMask.value)
      })
    }

    componentWillUnmount() {
      this.iMask.destroy()
      // @TODO find if I have to remove the callbacks
      // this.iMask.off("accept", log)
      // this.iMask.off("complete")
    }

    constructor(props) {
      super(...props)
    }

    render() {
      return (
        <ComposedComponent
          {...this.props}

          // This probably will change, support styled-components
          // inputRef is related to it
          inputRef={el => this.element = el}
          onChange={this.onChange}
        />
      )
    }

    onChange = (event) => {
      console.log('onChange:Value', this.iMask.value)
      console.log('onChange:UnMaskedValue', this.iMask.unmaskedValue)
      console.log('OnChange:Event', event)

      // this.textMaskInputElement.update()
      //
      // if (typeof this.props.onChange === 'function') {
      //   this.props.onChange(event)
      // }
    }
  }
}

// usage

const Input = ({ inputRef, ...props }) => {
  return (
    <StyledInput
      {...props}
      innerRef={inputRef}
    />
  )
}
const FinalInput = iMaskEnhance(Input)

const iMask = {
      mask: '+{7}(000)000-00-00'
    }

<FinalInput
          type="text"
          placeholder={placeholder}
          iMask={iMask}
        />
uNmAnNeR commented 6 years ago

Thank you for your interest! Draft is almost done, but i have not tried to build it yet :) I will push something soon and we could polish it.

uNmAnNeR commented 6 years ago

@yordis Thank you for example, it helped a lot. I think plugin is generally done. I am going to do some tests, examples and docs. And bug fix of course...

yordis commented 6 years ago

@uNmAnNeR let me know how I can help, the PR have a bunch of comments that I had. I will be using this package for some dynamic form stuff in React ❤️ and trying to figure out how to use it on React Native, will be really nice to actually have them both for free ❤️

yordis commented 6 years ago

Btw I want to rise your attention with what I did for the ref in React. Because I am using styled-components you can assume that you can just inject ref={el => this.element = el} because on styled-components components you have no access to ref

uNmAnNeR commented 6 years ago

@yordis i try to answer the comments

// @TODO find what this means also updates UI
// @TODO update the options

i use componentWillReceiveProps to update options

// check if it is safe to update with the same props
// or if I have to do some checking

Yes, it is safe. Only changed options are updated.

//@TODO what updating UI means?
// masked.reset(); // UI will NOT be updated

Masked is low level abstraction used internaly without HTML-element binding. No need to use it directly.

// @TODO use this vs onChange from the input

onChange event does not matter for mask. Using accept and complete events is a proper way.

// This probably will change, support styled-components
// inputRef is related to it

I have not used StyledComponents. You better know. As I understand from your example inputRef is enough to extend any existed component.

Would be nice to support React Native!