Home > Back-end >  Argument of type 'string' is not assignable to parameter of type 'Element'
Argument of type 'string' is not assignable to parameter of type 'Element'

Time:09-10

I am Creating a Project that needs a section to resize when dragging one of the element corner bars, so I searched on Youtube and I found this guy "THE ART OF CODING" he did this feature without importing the packages but he did it in javascript and I am doing it in typescript so this Error is Showing in " Argument of type 'string' is not assignable to parameter of type 'Element "

import React, {
  useRef,
  useEffect
} from "react";
import styles from "./Resize.module.css";

const ResizeableComponents = ({
  children
}: any) => {
  const ref = useRef("#box"); // also try with null so the error : " Argument of type 'null' is not assignable to parameter of type 'Element' "
  const refLeft = useRef("#leftBar");
  const refTop = useRef("#topBar");
  const refRight = useRef("#rightBar");
  const refBottom = useRef("#bottomBar");

  useEffect(() => {
    const resizeableEle = ref.current;
    const styles = window.getComputedStyle(resizeableEle); // " Argument of type 'string' is not assignable to parameter of type 'Element "
    let width = parseInt(styles.width, 10);
    let height = parseInt(styles.height, 10);
    let x = 0;
    let y = 0;

    resizeableEle.style.top = "150px";
    resizeableEle.style.left = "150px";

    // Right resize
    const onm ouseMoveRightResize = (event) => {
      const dx = event.clientX - x;
      x = event.clientX;
      width = width   dx;
      resizeableEle.style.width = `${width}px`;
    };

    const onm ouseUpRightResize = (event) => {
      document.removeEventListener("mousemove", onm ouseMoveRightResize);
    };

    const onm ouseDownRightResize = (event) => {
      x = event.clientX;
      resizeableEle.style.left = styles.left;
      resizeableEle.style.right = null;
      document.addEventListener("mousemove", onm ouseMoveRightResize);
      document.addEventListener("mouseup", onm ouseUpRightResize);
    };

    // Top resize
    const onm ouseMoveTopResize = (event) => {
      const dy = event.clientY - y;
      height = height - dy;
      y = event.clientY;
      resizeableEle.style.height = `${height}px`;
    };

    const onm ouseUpTopResize = (event) => {
      document.removeEventListener("mousemove", onm ouseMoveTopResize);
    };

    const onm ouseDownTopResize = (event) => {
      y = event.clientY;
      const styles = window.getComputedStyle(resizeableEle);
      resizeableEle.style.bottom = styles.bottom;
      resizeableEle.style.top = null;
      document.addEventListener("mousemove", onm ouseMoveTopResize);
      document.addEventListener("mouseup", onm ouseUpTopResize);
    };

    // Bottom resize
    const onm ouseMoveBottomResize = (event) => {
      const dy = event.clientY - y;
      height = height   dy;
      y = event.clientY;
      resizeableEle.style.height = `${height}px`;
    };

    const onm ouseUpBottomResize = (event) => {
      document.removeEventListener("mousemove", onm ouseMoveBottomResize);
    };

    const onm ouseDownBottomResize = (event) => {
      y = event.clientY;
      const styles = window.getComputedStyle(resizeableEle);
      resizeableEle.style.top = styles.top;
      resizeableEle.style.bottom = null;
      document.addEventListener("mousemove", onm ouseMoveBottomResize);
      document.addEventListener("mouseup", onm ouseUpBottomResize);
    };

    // Left resize
    const onm ouseMoveLeftResize = (event) => {
      const dx = event.clientX - x;
      x = event.clientX;
      width = width - dx;
      resizeableEle.style.width = `${width}px`;
    };

    const onm ouseUpLeftResize = (event) => {
      document.removeEventListener("mousemove", onm ouseMoveLeftResize);
    };

    const onm ouseDownLeftResize = (event) => {
      x = event.clientX;
      resizeableEle.style.right = styles.right;
      resizeableEle.style.left = null;
      document.addEventListener("mousemove", onm ouseMoveLeftResize);
      document.addEventListener("mouseup", onm ouseUpLeftResize);
    };

    // Add mouse down event listener
    const resizerRight = refRight.current;
    resizerRight.addEventListener("mousedown", onm ouseDownRightResize);
    const resizerTop = refTop.current;
    resizerTop.addEventListener("mousedown", onm ouseDownTopResize);
    const resizerBottom = refBottom.current;
    resizerBottom.addEventListener("mousedown", onm ouseDownBottomResize);
    const resizerLeft = refLeft.current;
    resizerLeft.addEventListener("mousedown", onm ouseDownLeftResize);

    return () => {
      resizerRight.removeEventListener("mousedown", onm ouseDownRightResize);
      resizerTop.removeEventListener("mousedown", onm ouseDownTopResize);
      resizerBottom.removeEventListener("mousedown", onm ouseDownBottomResize);
      resizerLeft.removeEventListener("mousedown", onm ouseDownLeftResize);
    };
  }, []);

  return ( <
    div className = {
      styles.container
    } >
    <
    div ref = {
      ref
    }
    id = "box"
    className = {
      styles.resizeable
    } >
    <
    div ref = {
      refLeft
    }
    id = "leftBar"
    className = {
      `${styles.resizer} ${styles.resizerl}`
    } >
    <
    /div> <
    div ref = {
      refTop
    }
    id = "topBar"
    className = {
      `${styles.resizer} ${styles.resizert}`
    } >
    <
    /div> <
    div ref = {
      refRight
    }
    id = "rightBar"
    className = {
      `${styles.resizer} ${styles.resizerr}`
    } >
    <
    /div> <
    div ref = {
      refBottom
    }
    id = "bottomBar"
    className = {
      `${styles.resizer}${styles.resizerb}`
    } >
    <
    /div> < /
    div > <
    /div>
  );
};

export default ResizeableComponents;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

Resize.module.css

.container {
    border-radius: 5px;
    width: 100vw;
    height: 100vh;
    background: #FFBC97;
    position: relative;
}

.resizeable {
    position: absolute;
    border: 2px solid #533535;
    width: 100px;
    height: 100px;
    border-radius: 3px;
    display: flex;
    justify-content: center;
    align-items: center;
    min-width: 15px;
    min-height: 15px;
}

.resizer {
    position: absolute;
    background: black;
}

.resizerr {
    cursor: col-resize;
    height: 100%;
    right: 0;
    top: 0;
    width: 5px;
}

.resizert {
    cursor: row-resize;
    height: 5px;
    left: 0;
    top: 0;
    width: 100%;
}

.resizerb {
    cursor: row-resize;
    height: 5px;
    left: 0;
    bottom: 0;
    width: 100%;
}

.resizerl {
    cursor: col-resize;
    height: 100%;
    left: 0;
    top: 0;
    width: 5px;
}

CodePudding user response:

I believe this line is the problem:

const ref = useRef("#box");

useRef is just useState but it's not causing a re-render when the value changes. I think you also need something like:

const ref = useRef(document.getElementById('box'))

CodePudding user response:

At first you are assigning ref value to a string, so the type of ref is MutableRefObject<string> which means that ref.current is expected to be a string, what you want is to attach the ref to the dom element on the first render like you did <div ref = {ref}/>, it will then be available in useEffect because it runs after the render. To correct this, explicitly type ref to

const ref= React.useRef<HTMLDivElement>(null);
  • Related