From c601399c34b7d2fe25454741d90bd92c7b5d8e20 Mon Sep 17 00:00:00 2001 From: Julian Roeland Date: Tue, 1 Oct 2024 16:46:09 +0200 Subject: [PATCH] :sparkles: - feat: autofocus useprompt --- src/hooks/dialog/useprompt.tsx | 105 ++++++++++++++++++++++----------- 1 file changed, 69 insertions(+), 36 deletions(-) diff --git a/src/hooks/dialog/useprompt.tsx b/src/hooks/dialog/useprompt.tsx index cc3e548a..f86969e7 100644 --- a/src/hooks/dialog/useprompt.tsx +++ b/src/hooks/dialog/useprompt.tsx @@ -1,4 +1,4 @@ -import React, { useContext } from "react"; +import React, { useContext, useEffect } from "react"; import { Form, ModalProps, P } from "../../components"; import { ModalServiceContext } from "../../contexts"; @@ -12,18 +12,6 @@ export const usePrompt = () => { const dialog = useDialog(); const { setModalProps } = useContext(ModalServiceContext); - /** - * Shows a prompt dialog with a confirmation callback and an optional - * cancellation callback. - * @param title - * @param message - * @param label - * @param labelConfirm - * @param labelCancel - * @param onConfirm - * @param onCancel - * @param modalProps - */ const fn = ( title: string, message: React.ReactNode, @@ -36,29 +24,15 @@ export const usePrompt = () => { ) => { dialog( title, - <> - {typeof message === "string" ?

{message}

: message} -
{ - setModalProps({ open: false }); - onCancel?.(); - }, - }, - ]} - validateOnChange={true} - onSubmit={(_, { message }) => { - setModalProps({ open: false }); - onConfirm(message as string); - }} - /> - , + , undefined, { allowClose: false, ...modalProps }, ); @@ -66,3 +40,62 @@ export const usePrompt = () => { return fn; }; + +const PromptForm = ({ + message, + label, + labelConfirm, + labelCancel, + onConfirm, + onCancel, + setModalProps, +}: { + message: React.ReactNode; + label: string; + labelConfirm: string; + labelCancel: string; + onConfirm: (message: string) => void; + onCancel?: () => void; + setModalProps: (props: Partial) => void; +}) => { + useEffect(() => { + // Delay the focus slightly to ensure modal and form are fully rendered + const timer = setTimeout(() => { + // We focus a form element, and if none are found, we focus the submit button, and otherwise none + const formElement: HTMLFormElement | null = document.querySelector( + "form input , form textarea , form select , form button[type=submit]", + ); + if (formElement) { + formElement.focus(); + } + }, 100); + + return () => clearTimeout(timer); + }, []); + + return ( + <> + {typeof message === "string" ?

{message}

: message} + { + setModalProps({ open: false }); + onCancel?.(); + }, + }, + ]} + validateOnChange={true} + onSubmit={(_, { message }) => { + setModalProps({ open: false }); + onConfirm(message as string); + }} + /> + + ); +};