-
-
Notifications
You must be signed in to change notification settings - Fork 251
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Compatible with React Native #12
Comments
Yes, this is not the only one, factory.js also seems to be incompatible because of circular dependencies. |
@yordis I fixed this. |
@uNmAnNeR I can help you out with the RN but I need to know from you which events would you need from the inputs for |
@yordis ok, here it is: el.addEventListener('keydown', ...)
el.addEventListener('input', ...)
el.addEventListener('drop', ...) // just disables
el.addEventListener('click', ...)
el.addEventListener('change' ...)
// ...and remove counterparts
el.selectionStart
el.selectionEnd
el.setSelectionRange(...);
get/set el.value
document.activeElement |
@uNmAnNeR I will port my iMask to the React Native code today so I will have to deal with this. |
@yordis How did this end up going? |
@yordis Sure, but i think it is possible to do like this: // RN -> React Plugin Mixin wraps RNTextInput to DOMlikeInput -> pass to IMask
// e.g
class TextInputAdapter {
constructor (nativeElement) {
this.nativeElement = nativeElement;
}
addEventListener(ev, handler) {
if (ev === 'input') this.nativeElement.onChangeText(handler);
}
// ...
} |
class Input extends React.Component {
// all the states happen here as well
// unless specific Adapter needs to handle
// some internals before letting this component
// to know about it
state = {}
render() {
const InputAdapter = this.props.adapter
const inputProps = {
// this is a well defined protocol for any Input Adapter
// for example
onChange(x: string): void
// every Adapter HAVE to call the same set of data
// on the web normally the events give you `event` object
// and in Native it will give you the actual `text`
// both have to send back the same data structure
}
return (
<InputAdapter {...inputProps}/>
)
}
// here is where all the callbacks management happens
// no data management happens inside the adapters
// example
onChange(alwaysExpectTheText) {
// do what you need to do
}
}
// package name: imask-react-dom
class IMaskDOMInput extends Component {
// do whatever the DOM API requires you to do
// the onChange needs to clean up the data before
// sending to the callback because the DOM event
handleOnChange(event) {
const text = event.target.value
this.props.onChange(text)
}
}
class IMaskInput extends Component {
render() {
<Input
{...props }
// notice this
adapter={IMaskDOMInput}
>
}
}
// package name: imask-react-native
class IMaskNativeInput extends Component {
// do whatever the DOM API requires you to do
// the onChange needs to clean up the data before
// sending to the callback because the DOM event
handleOnChange(text) {
this.props.onChange(text)
}
}
class IMaskInput extends Component {
render() {
<Input
{...props }
// notice this
adapter={IMaskNativeInput}
>
}
} |
@uNmAnNeR something around that API design. Normally you will have 2 packages, each package the ONLY thing it defines is the Adapter you will be using and both of them will have the same HOC so you could use the same component name in no matter which platform. Each adapter do whatever it needs to be able to communicate with the Internal HOC that actually manage the iMask interactions needs. I dont like this
because the component where you are doing that have to know about both platforms, using the Adapter approach your HOC |
Probably the just make it agnostic of the low level components and just manage the iMask interactions with React I guess |
@yordis But your interface UIElement {
value (string) // ok
selectionStart (): number // ok
selectionEnd (): number // ok
setSelectionRange (function (number, number): void) // ok
// addEventListener (function (string, Function): void) // not ok, will be split to:
onInput ()
onKeyDown ()
onDrop ()
onClick ()
onChange ()
// removeEventListener (function (string, Function): void) // not ok, will be replaced with passing null to methods above
} |
Well, I think that you can't use that class on React but you could make it work as long as you let the React component to know about the data changes but even that the way you would pass down the callbacks it is another concern as well, normally you would use HOC Definitely you could use that class under This is how I see it
As you notice React DOM Input could use the UIElement because it is just DOM stuff but I dont see that working for RN. I thikn you can't do In the case of the Web maybe is different because you can always just ask for the native element and register callbacks and stuff like that directly but I dont think that exists on RN but please dig in more. |
@yordis hi again! :) I hacked a little on RN. I supposed to end up with something like: import React from 'react';
import { StyleSheet, Text, View, TextInput } from 'react-native';
import { IMaskMixin } from 'react-imask';
class Adapter {
constructor (el) {
this.el = el;
}
addEventListener (event, handler) {
// switch (event) {
// case 'keydown': return this.el.onKeyPress(handler);
// case 'input': return this.el.onChange(handler);
// }
}
removeEventListener (event) {
// TODO
}
selectionStart () {
return 0;
// return this.el.selection.start;
}
selectionEnd () {
return 0;
// return this.el.selection.end;
}
setSelectionRange (start, end) {
// this.el.selection = {start, end};
}
get value () {
return 'asd';
// return this.el.value;
}
set value (value) {
// this.el.value = value;
}
}
const MaskedTextInput = IMaskMixin(({inputRef, ...props}) => (
<TextInput
{...props}
ref={el => inputRef(new Adapter(el))}
/>
));
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<MaskedTextInput
style={{
height: 40,
width: 100,
borderColor: 'gray',
borderWidth: 1
}}
mask='000'
editable = {true}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
}); But RN element in |
@yordis Hello! |
Merged in master. Plugin was released with version 0.0.x and then made |
@uNmAnNeR Is it ready then? |
@yordis it's not production ready yet. |
will be released as is, does not make sense to wait one more year for bug fixing in RN |
@uNmAnNeR did you ever found a fix for the rerender bug for react native? |
@TNAJanssen I tried to make it work a long time ago, but with no luck. Too many things did not work as expected on different systems, so I gave up. If someone can restore my faith with some good PR, I'd be happy to continue supporting it. |
Lines like this https://github.com/uNmAnNeR/imaskjs/blob/gh-pages/src/imask.js#L29 wouldn't work.
The text was updated successfully, but these errors were encountered: