hc-oss / react-tag-input-component

lightweight react component for tag(s) input
https://codesandbox.io/s/react-tag-input-component-rgf97
MIT License
80 stars 36 forks source link

Feature request: Forward ref to the input element #42

Open AnsonH opened 1 year ago

AnsonH commented 1 year ago

Motivation

I'm developing a feature where I wish to get the current value of the internal input.rti--input element.

Suppose the user starts typing the first tag in an empty tag input component. If the user forgets to press "Enter" to add the tag, the value state remains an empty array.

image

This can be problematic if the user submits the form now since we're submitting [] instead of ["papaya"] in the form data. I want to be more lenient by auto-inserting any value in the <input> element into the value state whenever the user submits.

Suggested API Change

I suggest that we can expose a new prop called ref, which will be forwarded to the <input> element of classname rti--input. So it would look something like:

const [selected, setSelected] = useState(["papaya"]);
const ref = useRef<HTMLInputElement>(null);  // 👈

<TagsInput
  ref={ref}  // 👈
  value={selected}
  onChange={setSelected}
  name="fruits"
  placeHolder="enter fruits"
/>
AnsonH commented 1 year ago

Update: I'm able to find a workaround by using onBlur to solve the above problem without the need of adding forward refs.

It may be still useful to implement forward ref even though my use case no longer needs it. Feel free to close this issue if you don't find this feature necessary :smile:


I can make use of onBlur prop to add any value in the <input> element to the array state whenever the input loses focus:

Edit react-tag-input-component - Add item on Blur

export default function App() {
  const [selected, setSelected] = useState(["papaya"]);
  return (
    <div>
      <h1>Add Fruits</h1>
      <pre>{JSON.stringify(selected)}</pre>
      <TagsInput
        value={selected}
        onChange={setSelected}
        // 👇 Adds the value in input to `selected` when loses focus
        onBlur={(e) => {
          const value = e.target.value;
          if (!selected.includes(value) && value !== "") {
            setSelected([...selected, value]);
            e.target.value = "";
          }
        }}
        name="fruits"
        placeHolder="enter fruits"
      />
      <em>press enter to add new tag</em>
    </div>
  );
}

Demo (the fruit is added automatically whenever I click away without pressing "Enter"):

https://user-images.githubusercontent.com/57580593/209638191-73a1e6ca-9d75-4d92-9aa2-cd4a3686f9d2.mp4

Alekzv9 commented 1 year ago

Forward ref will be really helpful because it can be integrated with libraries like form hooks