maxeth / react-type-animation

A React typewriter animation based on typical with extended functionality and customization.
https://react-type-animation.netlify.app/
MIT License
427 stars 24 forks source link

Using inside text input/textarea #32

Closed hjf closed 10 months ago

hjf commented 1 year ago

I'd like to use this as the placeholder of a textarea. Obviously it'd need to be text only, and not a whole component.

Maybe it can be split into a hook, so the text can be used as the placeholder prop in a Textarea element?

maxeth commented 1 year ago

Hey,

the package currently natively modifies DOM elements without actual React state, but we could also put the functionality of the type function into a standalone, exported hook.

For now, you could just render a dummy TypeAnimation component with style={{display:"none"}}, pass a ref to the TypeAnimation component and use something like MutationObserver to listen for any DOM changes to the element associated to the ref. Upon changes, you would grab its content via ref.current.textContent and set it in some state value, getting the most up-to-date text written by the component.


Or simplified without MutationObserver:

export function CallbackExample() {
  const [tick, setTick] = useState(0);

// narrow down this component as much as possible — eg make it just a wrapper for a TypeAnimation component — 
// so these re-renders dont cause performance issues
  useEffect(() => {
    const t = setTimeout(() => {
      setTick((p) => p + 1);
    }, 10);

    return () => clearInterval(t);
  }, [tick]);

  const [refNode, setRefNode] =
    useState<MutableRefObject<HTMLSpanElement>['current']>();

  const refCallback = useCallback(
    (nodeContent: MutableRefObject<HTMLSpanElement>['current']) => {
      console.log(nodeContent);
      setRefNode(nodeContent);
    },
    []
  );

  return (
    <>
      {refNode && <div>{refNode.textContent}</div>}

        <TypeAnimation
         style={{display:"none"}}
          ref={refCallback}
          sequence={["a", "b", "c"]}
        />

    </>
  );
}

So with refNode.textContent you always have access to the latest typed-out value and can do whatever with it.

It's not optimal but it should work :)