react-input-trigger icon indicating copy to clipboard operation
react-input-trigger copied to clipboard

Doesn't work with MaterialUI TextFields

Open dominikbulaj opened this issue 5 years ago • 11 comments

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?

dominikbulaj avatar Mar 07 '19 13:03 dominikbulaj

@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 :)

charly-palencia avatar Jun 16 '19 21:06 charly-palencia

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...

TonisPiip avatar Jun 17 '19 15:06 TonisPiip

@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

charly-palencia avatar Jun 17 '19 16:06 charly-palencia

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.

TonisPiip avatar Jun 17 '19 18:06 TonisPiip

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

charly-palencia avatar Jun 18 '19 21:06 charly-palencia

@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 🤞 .

charly-palencia avatar Jun 18 '19 21:06 charly-palencia

@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!

rheaditi avatar Jun 22 '19 12:06 rheaditi

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 🙂 !

abinavseelan avatar Jun 22 '19 13:06 abinavseelan

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

Thanks.

tylertyssedal avatar Jul 15 '19 14:07 tylertyssedal

Any update on this @abinavseelan ?

mckenzieja avatar May 07 '20 19:05 mckenzieja

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

rameshjanjyam avatar Sep 18 '20 17:09 rameshjanjyam