Skip to content

Instantly share code, notes, and snippets.

@wildeyes
Created March 15, 2024 17:52
Show Gist options
  • Save wildeyes/11ab72a70b4a5e3774e75fc3d60d9d2d to your computer and use it in GitHub Desktop.
Save wildeyes/11ab72a70b4a5e3774e75fc3d60d9d2d to your computer and use it in GitHub Desktop.
Making dialog element return value awaitable with useImperativeHandle, dialog element, form method dialog
"use client";
import { AddPersonModal, AddPersonModalHandle } from "@/app/form";
import { useRef } from "react";
export function AddBtn() {
const ref = useRef<AddPersonModalHandle>(null);
return (
<>
<AddPersonModal ref={ref} />
<button
className='bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded'
onClick={() => {
const person = ref.current?.show();
console.log(person);
}}
>
Add
</button>
</>
);
}
import { forwardRef, useImperativeHandle, useRef } from "react";
export type AddPersonModalHandle = {
show: () => void;
hide: () => void;
};
export const AddPersonModal = forwardRef(function AddPerson(props, ref) {
const modal = useRef<HTMLDialogElement>(null);
useImperativeHandle(
ref,
() =>
({
yield: () => {
return new Promise((resolve) => {
modal.current?.showModal();
modal.current?.addEventListener("close", () => {
resolve(modal.current?.returnValue);
});
});
},
show: () => {
modal.current?.showModal();
},
hide: () => {
modal.current?.close();
},
} as AddPersonModalHandle)
);
return (
<dialog id='favDialog' ref={modal}>
<form method='dialog'>
<input type='submit' aria-label='close' value='X' name='Xbutton' formNoValidate />
<p>
<label>
Name:
<input type='text' name='name' required />
</label>
<button type='submit'>Add</button>
</p>
</form>
</dialog>
);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment