2

I'm trying to import a dialog component from daisy ui but I'm getting the following error message:

Unsafe member access .showModal on an `any` value.eslint@typescript-eslint/no-unsafe-member-access
Unsafe call of an `any` typed value.eslint@typescript-eslint/no-unsafe-call
Unsafe return of an `any` typed value.eslint@typescript-eslint/no-unsafe-return
Property 'my_modal_2' does not exist on type 'Window & typeof globalThis'.ts(2339)

I didn't tamper with the default code:

<button
              className="btn"
              onClick={() => window.my_modal_2.showModal()}
            >
              open modal
            </button>
            <dialog id="my_modal_2" className="modal">
              <form method="dialog" className="modal-box">
                <h3 className="text-lg font-bold">Hello!</h3>
                <p className="py-4">Press ESC key or click outside to close</p>
              </form>
              <form method="dialog" className="modal-backdrop">
                <button>close</button>
              </form>
            </dialog>

Anyone know what's going on?

Mathew
  • 318
  • 11

3 Answers3

2

The example code is in javascript and consequently not type-safe in typescript which you use.

Try the following, which is a bit more verbose but should remove all ts errors:

<button
  className="btn"
  onClick={() => {
    if (document) {
      (document.getElementById('my_modal_2') as HTMLFormElement).showModal();
    }
  }}
>
tristndev
  • 367
  • 2
  • 14
1

TL;DR useRef

const myModal = useRef<HTMLDialogElement>(null)

return (
   <>
     <dialog className='modal' ref={myModal}>
       ...
     </dialog>
     <button onClick={() => myModal.current?.showModal()}>...<button>
   </>
)

Long answer

Usually any time you want to access something related to the DOM or the window object, your first thought when using React should be Refs.

Here, React docs give you a nice list of when to use Refs:

https://react.dev/learn/referencing-values-with-refs#when-to-use-refs

Quoting the docs:

Typically, you will use a ref when your component needs to “step outside” React and communicate with external APIs—often a browser API that won’t impact the appearance of the component.

Miguel Jara
  • 311
  • 2
  • 9
0

I'm using Next.js v13.4.19 with typescript and this worked for me:

You need to expand the global Window object like this:
*Note: This makes the my_modal_2 available in your whole project on the Window interface not just in your file

declare global {
  interface Window {
    my_modal_2: HTMLFormElement;
  }
}

Complete example:

"use client";

declare global {
  interface Window {
    cart_modal: HTMLFormElement;
  }
}

type Props = {};

const ModalComponent = (props: Props) => {
  return (
    <>
      <button className="btn" onClick={()=>window.my_modal_2.showModal()}>open modal</button>
      <dialog id="my_modal_2" className="modal">
        <form method="dialog" className="modal-box">
          <h3 className="font-bold text-lg">Hello!</h3>
          <p className="py-4">Press ESC key or click outside to close</p>
        </form>
        <form method="dialog" className="modal-backdrop">
          <button>close</button>
        </form>
      </dialog>
    </>
  );
};