-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
✨ - feat: implemented useFormDialog hook
- Loading branch information
Showing
2 changed files
with
164 additions
and
77 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
import { | ||
AttributeData, | ||
Form, | ||
FormField, | ||
FormProps, | ||
ModalProps, | ||
P, | ||
} from "@maykin-ui/admin-ui"; | ||
import React, { useContext, useEffect } from "react"; | ||
|
||
import { ModalServiceContext } from "../../contexts"; | ||
import { useDialog } from "./usedialog"; | ||
|
||
/** | ||
* Returns a function which, when called: shows a form dialog with a | ||
* confirmation callback and an optional cancellation callback. | ||
*/ | ||
export const useFormDialog = () => { | ||
const dialog = useDialog(); | ||
|
||
/** | ||
* Shows a prompt dialog with a confirmation callback and an optional | ||
* cancellation callback. | ||
* @param title | ||
* @param message | ||
* @param fields | ||
* @param labelConfirm | ||
* @param labelCancel | ||
* @param onConfirm | ||
* @param onCancel | ||
* @param modalProps | ||
* @param formProps | ||
*/ | ||
const fn = ( | ||
title: string, | ||
message: React.ReactNode, | ||
fields: FormField[], | ||
labelConfirm: string, | ||
labelCancel: string, | ||
onConfirm: (data: AttributeData) => void, | ||
onCancel?: () => void, | ||
modalProps?: Partial<ModalProps>, | ||
formProps?: FormProps, | ||
) => { | ||
dialog( | ||
title, | ||
<> | ||
{typeof message === "string" ? <P>{message}</P> : message} | ||
<PromptForm | ||
message={message} | ||
fields={fields} | ||
labelConfirm={labelConfirm} | ||
labelCancel={labelCancel} | ||
onConfirm={onConfirm} | ||
onCancel={onCancel} | ||
formProps={formProps} | ||
/> | ||
</>, | ||
undefined, | ||
{ allowClose: false, ...modalProps }, | ||
); | ||
}; | ||
|
||
return fn; | ||
}; | ||
|
||
const PromptForm = ({ | ||
message, | ||
fields, | ||
labelConfirm, | ||
labelCancel, | ||
onConfirm, | ||
onCancel, | ||
formProps, | ||
}: { | ||
message: React.ReactNode; | ||
fields: FormField[]; | ||
labelConfirm: string; | ||
labelCancel: string; | ||
onConfirm: (data: AttributeData) => void; | ||
onCancel?: () => void; | ||
formProps?: FormProps; | ||
}) => { | ||
const { setModalProps } = useContext(ModalServiceContext); | ||
|
||
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" ? <P>{message}</P> : message} | ||
<Form | ||
fields={fields} | ||
labelSubmit={labelConfirm} | ||
secondaryActions={[ | ||
{ | ||
children: labelCancel, | ||
type: "button", | ||
variant: "secondary", | ||
onClick: () => { | ||
setModalProps({ open: false }); | ||
onCancel?.(); | ||
}, | ||
}, | ||
]} | ||
validateOnChange={true} | ||
onSubmit={(_, data) => { | ||
setModalProps({ open: false }); | ||
onConfirm(data); | ||
}} | ||
{...formProps} | ||
/> | ||
</> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters