Skip to content
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

Doesn't work with MaterialUI TextFields #10

Open
dominikbulaj opened this issue Mar 7, 2019 · 11 comments
Open

Doesn't work with MaterialUI TextFields #10

dominikbulaj opened this issue Mar 7, 2019 · 11 comments

Comments

@dominikbulaj
Copy link

dominikbulaj commented Mar 7, 2019

Hi,

I wanted to implement react-input-trigger to project I work on. There I use MaterialUI and TextFields.
However react-input-trigger fails with onStart

Uncaught TypeError: Failed to execute 'getComputedStyle' on 'Window': parameter 1 is not of type 'Element'.

My component is as simple as:

const TextFieldComponent = ({ input, meta: { touched, error }, ...custom }) => {

  const isError = Boolean(touched && error)
  let helperText = custom.label !== custom.helperText ? custom.helperText : undefined
  if (!helperText && error) {
    helperText = error
  }

  return <InputTrigger
    trigger={{
      keyCode: 51,// hash code
      shiftKey: true,
    }}
    onStart={(metaData) => { console.log(metaData) }}
  >
    <TextField
      error={isError}
      {...input}
      {...custom}
      helperText={helperText}
      variant="outlined"
      margin="normal"
    />
  </InputTrigger>
}

Seems error comes from dependency textarea-caret-position https://github.com/component/textarea-caret-position/blob/master/index.js#L71

Any idea how to make it work? It seems to me that it works only with html tags (textarea or input) and not React components, am I right?

@charly-palencia
Copy link

charly-palencia commented Jun 16, 2019

@abinavseelan branch bugfix/broken-ref is working perfectly for me with Material UI 🎉 !

    <InputTrigger
      trigger={{
        keyCode: 50,
        shiftKey: true,
      }}
      onStart={handleMention}
    >
      {setRef => {
        return <TextInputWithError {...props} inputRef={setRef} />; //wrapper for material ui text-field
      }}
    </InputTrigger>

Could you give some update about this Branch and when it'll be merged with master? I tried to work with an npm github reference but it didn't work properly. I had to copy your index.js and utils.js and that's how I know it's working. Thanks! 🙏

Notes:
the only warning that I noticed for this branch is this one
Warning: Failed prop type: Invalid prop childrenof typefunctionsupplied toInputTrigger, expected a single ReactElement.
And it's a simple ProptyType issue :)

@TonisPiip
Copy link

The reason github ref doesn't work is because the built files aren't included in the github repo, They're somehow built inside npm's servers, I'm not too familiar with their system.

However if you use the branch with the following: git://github.com/abinavseelan/react-input-trigger.git#bugfix/broken-ref thenrun npm install; npm run build inside .../yourproject/node_modules/react-input-trigger you might be able to get it working without making a fork.
Might want to add it to your build scripts to make sure it's updated and built on new installs... but not ideal...

@charly-palencia
Copy link

@CylonOven Thanks for the reply. Unfortunately, this is not a personal project and I won't be able to include an extra step such a npm run build for the team in this case. I would like that use this component because is really awesome but the only way for me now is that this broken-ref branch will be up soon. Thanks again

@TonisPiip
Copy link

TonisPiip commented Jun 17, 2019

One other option, in the case that this project isn't going to respond to any of their PRs / issues is to create a new file that imports this component, then over-rides the methods that have been updated / you have problems with, with working methods, then re-export it, and input this new component rather than the original .

I'm using the quilll editor, which required a lot of hacking inside this package due to it's not a normal HTML element, and if I didn't have an option to use own own fork of the project that's what I would do.

@charly-palencia
Copy link

@CylonOven Yeah, that sounds like a good idea, Thanks man! ⭐️

@charly-palencia
Copy link

@CylonOven draft version for my InputTrigger extension

import React from "react";
import PropTypes from "prop-types";

import ReactInputTrigger from "react-input-trigger";

// CUSTOM function override of react-input-trigger,https://github.com/abinavseelan/react-input-trigger
/* eslint-disable */
class InputTrigger extends ReactInputTrigger {
  /*
   * Those changes have been made by the repository owner in branch bugfix/broken-ref. this file should be REMOVE once this PR will be merged with master.
   * */
  constructor(args) {
    super(args);

    this.setRef = this.setRef.bind(this);
    this.element = null;
  }

  setRef(element) {
    if (element && Object.hasOwnProperty.call(element, "current")) {
      this.element = element.current;
    } else {
      this.element = element;
    }
  }

  render() {
    const {
      children,
      endTrigger,
      onCancel,
      onStart,
      onType,
      trigger,
      ...rest
    } = this.props;

    return (
      <div
        role="textbox"
        tabIndex={-1}
        onKeyDown={this.handleTrigger}
        {...rest}
      >
        {children(this.setRef)}
      </div>
    );
  }
}

InputTrigger.propTypes = {
  ...InputTrigger.propTypes,
  children: PropTypes.oneOfType([PropTypes.element, PropTypes.func]).isRequired,
};

InputTrigger.defaultProps = {
  trigger: {
    keyCode: null,
    shiftKey: false,
    ctrlKey: false,
    metaKey: false,
  },
  onStart: () => {},
  onCancel: () => {},
  onType: () => {},
  endTrigger: () => {},
};

export default InputTrigger;

Hopefully, @abinavseelan will see this and he would like to merge his changes to master 🤞 .

@rheaditi
Copy link
Collaborator

rheaditi commented Jun 22, 2019

@charly-palencia, @dominikbulaj So sorry about not being able to respond to these issues earlier!
Work has been 🤯 💥 😅 !

We've published a beta version [email protected] [email protected] with the changes from bugfix/broken-ref. We'd love if you could try it out and let us know if it works for you. We'll test it out for a couple more use cases and publish a major version soon.

npm install [email protected]

Thanks a lot for your support!

@abinavseelan
Copy link
Owner

We're still updating the docs to reflect this change before we publish the release. Meanwhile, in order to test this out please use the following steps 🙂 :

If using React 16+:

class DemoComponent extends React.Component {
    constructor() {
        // Other code

        this.inputElement = React.createRef(); // Set up a ref
    }

    render() {
        return (
            <InputTrigger
                trigger={{
                    keyCode: 51, // hash code
                    shiftKey: true,
                }}
                onStart={(metaData) => { console.log(metaData) }}

                inputRef={() => this.inputElement} // Important(New prop): Must be a function that returns the element's ref.
            >
                <textarea ref={this.inputElement} />
            </InputTrigger>
        )
    }
}

If using React 15+:

class DemoComponent extends React.Component {
    constructor() {
        // Other code

        this.inputElement = React.createRef(); // Set up a ref
    }

    render() {
        return (
            <InputTrigger
                trigger={{
                    keyCode: 51, // hash code
                    shiftKey: true,
                }}
                onStart={(metaData) => { console.log(metaData) }}

                inputRef={() => this.inputElement} // Important(New prop): Must be a function that returns the element's ref.
            >
                <textarea ref={(el) => { this.inputElement = el; }} />
            </InputTrigger>
        )
    }
}

As highlighted in the issue, the existing version of react-input-trigger does not work when using non-native input and textarea elements, for example Material UI's TextField.

The following is how the new version plans to solve this, with the new inputRef prop in <InputTrigger />

import TextField from 'material-ui/core/TextField';

class DemoComponent extends React.Component {
    constructor() {
        // Other code

        this.inputElement = React.createRef(); // Set up a ref
    }

    render() {
        return (
            <InputTrigger
                trigger={{
                    keyCode: 51, // hash code
                    shiftKey: true,
                }}
                onStart={(metaData) => { console.log(metaData) }}

                inputRef={() => this.inputElement} // Important(New prop): Must be a function that returns the element's ref.
            >
                <TextField
                    inputRef={this.inputElement} // This is a prop provided by Material UI to get the ref to the input element.
                />
            </InputTrigger>
        )
    }
}

Let us know if there are any issues 🙂 !

@tylertyssedal
Copy link

Do we have an idea of when the new release featuring inputRef will be out?

Thanks.

@mckenzieja
Copy link

Any update on this @abinavseelan ?

@rameshjanjyam
Copy link

thank you for that material ui textfield example above. adding input ref is working but I am seeing this warning in console

 react-input-trigger: selectionStart/selectionEnd is missing in element ref. Please ensure the ref returned from
      'inputRef' is a valid input or textarea element

by the way I am using version 2.0.0-beta-1. how can I fix that warning

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants