@chris-c-brine/form-dialog 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +325 -0
  2. package/dist/components/AutoGrid.d.ts +12 -0
  3. package/dist/components/BaseDialog.d.ts +13 -0
  4. package/dist/components/BlackoutDialog.d.ts +23 -0
  5. package/dist/components/FormDialog.d.ts +11 -0
  6. package/dist/components/FormDialogActions.d.ts +15 -0
  7. package/dist/components/GridSpacer.d.ts +2 -0
  8. package/dist/components/PaperForm.d.ts +6 -0
  9. package/dist/components/PersistForm.d.ts +5 -0
  10. package/dist/components/buttons/FormCancelButton.d.ts +5 -0
  11. package/dist/components/buttons/FormResetButton.d.ts +6 -0
  12. package/dist/components/buttons/FormSubmitButton.d.ts +9 -0
  13. package/dist/components/buttons/LoadingButton.d.ts +8 -0
  14. package/dist/components/dialogs/BaseDialog.d.ts +13 -0
  15. package/dist/components/dialogs/BlackoutDialog.d.ts +23 -0
  16. package/dist/components/dialogs/FormDialog.d.ts +11 -0
  17. package/dist/components/dialogs/FormDialogActions.d.ts +15 -0
  18. package/dist/components/forms/PaperForm.d.ts +6 -0
  19. package/dist/components/forms/PersistForm.d.ts +5 -0
  20. package/dist/components/index.d.ts +10 -0
  21. package/dist/hooks/index.d.ts +5 -0
  22. package/dist/hooks/useDialog.d.ts +12 -0
  23. package/dist/hooks/useFormDialog.d.ts +1 -0
  24. package/dist/hooks/useMaxAttempts.d.ts +5 -0
  25. package/dist/hooks/useOnMount.d.ts +6 -0
  26. package/dist/hooks/usePersistedForm.d.ts +7 -0
  27. package/dist/index.d.ts +4 -0
  28. package/dist/index.esm.js +390 -0
  29. package/dist/index.esm.js.map +1 -0
  30. package/dist/index.js +390 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/state/FormDialogContext.d.ts +9 -0
  33. package/dist/state/FormDialogProvider.d.ts +5 -0
  34. package/dist/state/createFormChangeStore.d.ts +24 -0
  35. package/dist/utils/ThemeBridge.d.ts +7 -0
  36. package/dist/utils/applyDefaultFormDialogProps.d.ts +1417 -0
  37. package/dist/utils/deepCompare.d.ts +16 -0
  38. package/dist/utils/hasMaxAttempts.d.ts +5 -0
  39. package/dist/utils/index.d.ts +3 -0
  40. package/package.json +60 -0
package/README.md ADDED
@@ -0,0 +1,325 @@
1
+ # @chris-c-brine/form-dialog
2
+
3
+ Easy Form Dialogs with a persistable state!
4
+
5
+ A React component library that seamlessly integrates Material UI dialogs with React Hook Form, providing persistable form state, context-aware components, and simplified dialog management.
6
+
7
+ ## Installation
8
+
9
+ This package is currently private and intended for restricted access use.
10
+
11
+ ```bash
12
+ npm install @chris-c-brine/form-dialog
13
+ ```
14
+
15
+ ## Dependencies
16
+ This package has the following peer dependencies that need to be installed in your project:
17
+ - @emotion/react: ^11.14.0
18
+ - @emotion/styled: ^11.14.0
19
+ - @mui/icons-material: ^7.1.0
20
+ - @mui/material: ^7.1.0
21
+ - lodash: ^4.17.21
22
+ - react: ^19.1.0
23
+ - react-dom: ^19.1.0
24
+ - react-hook-form: ^7.56.2
25
+ - react-hook-form-mui: ^7.6.0
26
+ - zustand: ^5.0.4
27
+
28
+ ## Features
29
+
30
+ - **Integrated Form Dialogs**: Combines Material UI dialogs with React Hook Form
31
+ - **Persistable State**: Store form data across page refreshes using Zustand
32
+ - **Simplified Workflow**: Streamlined API for common form dialog patterns
33
+ - **Context-Aware Components**: Dialog components that share form state
34
+ - **TypeScript Support**: Fully typed for a better developer experience
35
+ - **Customizable UI**: Extends Material UI components
36
+
37
+ ## Known Issues
38
+ - **Max Attempts & Persistence**: PersistForm does not yet support Max attempts
39
+ - **A11Y on Form Dialog Close**: Blocked aria-hidden on an element because its descendant retained focus. The focus must not be hidden from assistive technology users. Avoid using aria-hidden on a focused element or its ancestor. Consider using the inert attribute instead, which will also prevent focus. For more details, see the aria-hidden section of the WAI-ARIA specification at https://w3c.github.io/aria/#aria-hidden.
40
+ Element with focus...
41
+ -
42
+
43
+ ```tsx
44
+ // LoginFormBase.tsx
45
+ import {
46
+ TextFieldElement,
47
+ PasswordElement,
48
+ type PasswordElementProps,
49
+ useFormContext,
50
+ } from "react-hook-form-mui";
51
+ import { memo, useEffect } from "react";
52
+ import { useFormDialog, AutoGrid, type AutoGridProps } from "@chris-c-brine/form-dialog";
53
+
54
+ export type NameProp = {name?: string; };
55
+ export type LoginFormProps = NameProp & Pick<AutoGridProps, "columnCount">;
56
+
57
+ const LoginFormBase = memo(function ({ name, columnCount = 1 }: LoginFormProps) {
58
+ const { disabled } = useFormDialog();
59
+
60
+ useEffect(() => formNameLog(name), [name]);
61
+
62
+ return (
63
+ <AutoGrid
64
+ columnCount={columnCount}
65
+ columnSpacing={2}
66
+ rowSpacing={1}
67
+ components={[
68
+ <UserName key={`${name}-username`} disabled={disabled} />,
69
+ <Password key={`${name}-password`} disabled={disabled} />,
70
+ ]}
71
+ />
72
+ );
73
+ });
74
+
75
+ LoginFormBase.displayName = "LoginForm";
76
+
77
+ export default LoginFormBase;
78
+
79
+ /**
80
+ * Inputs
81
+ */
82
+ const UserName = memo(({ disabled }: Pick<PasswordElementProps, "disabled">) => (
83
+ <TextFieldElement
84
+ name="username"
85
+ label="Username"
86
+ required
87
+ autoFocus
88
+ autoComplete="off"
89
+ fullWidth
90
+ margin={"dense"}
91
+ size={"medium"}
92
+ disabled={disabled}
93
+ slotProps={{
94
+ inputLabel: { shrink: true },
95
+ }}
96
+ />
97
+ ));
98
+
99
+ UserName.displayName = "UserName";
100
+
101
+ const Password = function ({ disabled }: Pick<PasswordElementProps, "disabled">) {
102
+ const { setValue, getValues } = useFormContext();
103
+ const password = getValues("password");
104
+
105
+ useEffect(() => {
106
+ if (disabled && password !== "") {
107
+ setValue("passwordDisabled", "");
108
+ }
109
+ }, [disabled, setValue, password]);
110
+
111
+ return (
112
+ <PasswordElement
113
+ name={"passwordDisabled"}
114
+ label={"Password"}
115
+ fullWidth
116
+ required
117
+ autoComplete="off"
118
+ size="medium"
119
+ margin={"dense"}
120
+ disabled={disabled}
121
+ slotProps={{
122
+ inputLabel: { shrink: true },
123
+ }}
124
+ {...(disabled && { renderIcon: () => <></> })}
125
+ />
126
+ );
127
+ };
128
+ Password.displayName = "Password";
129
+ ```
130
+ ```tsx
131
+ // LoginDialog.tsx
132
+ import { FormDialog, FormDialogActions, type FormDialogProps, PersistForm } from "@chris-c-brine/form-dialog";
133
+ import { useMemo, type FC } from "react";
134
+ import { useForm } from "react-hook-form-mui";
135
+ import LoginFormBase from "../forms/LoginFormBase";
136
+ import {
137
+ defaultLoginFormValues,
138
+ type LoginForm,
139
+ type SubmitLogin,
140
+ } from "@pages/LoginPage/LoginPageConstants";
141
+ import { useDialog } from "@hooks";
142
+ import { devLog } from "@utils";
143
+
144
+ const formKey = "dialog-login-form";
145
+
146
+ /* Basic Form Dialog Test */
147
+ type LoginDialogProps = Pick<ReturnType<typeof useDialog>, "dialogProps"> &
148
+ Pick<FormDialogProps<LoginForm>, "onClose"> & {
149
+ handleSubmit: SubmitLogin;
150
+ };
151
+
152
+ const LoginDialog: FC<LoginDialogProps> = ({ dialogProps, handleSubmit }) => {
153
+ const formContext = useForm({ defaultValues: defaultLoginFormValues });
154
+ const loginForm = useMemo(() => <LoginFormBase name={formKey} columnCount={2} />, []);
155
+
156
+ return (
157
+ <FormDialog
158
+ {...dialogProps}
159
+ formProps={{ onSuccess: handleSubmit, formContext, onError: devLog("Form Errors") }}
160
+ title={"Basic Form Dialog Test"}
161
+ titleProps={{ variant: "h5", textAlign: "center" }}
162
+ actions={<FormDialogActions resetProps={{ formKey }} submitProps={{ maxAttempts: 3 }} />}
163
+ >
164
+ <PersistForm formName={formKey}>{loginForm}</PersistForm>
165
+ </FormDialog>
166
+ );
167
+ };
168
+
169
+ LoginDialog.displayName = "LoginDialog";
170
+
171
+ export default LoginDialog;
172
+ ```
173
+ ```tsx
174
+ // LoginForm.tsx
175
+ import { Lock as LockIcon } from "@mui/icons-material";
176
+ import { Box, Typography, type TypographyProps } from "@mui/material";
177
+ import { type SubmitLogin, defaultLoginFormValues } from "@pages/LoginPage/LoginPageConstants";
178
+ import { devLog } from "@utils";
179
+ import { merge } from "lodash";
180
+ import type { FC, PropsWithChildren } from "react";
181
+ import LoginFormBase from "./LoginFormBase";
182
+ import { FormDialogActions, FormDialogProvider, PaperForm } from "@chris-c-brine/form-dialog";
183
+
184
+ const AltIcon = () => <LockIcon sx={{ mr: 1, fontSize: 20 }} />;
185
+
186
+ interface LoginFormProps extends PropsWithChildren {
187
+ onSuccess: SubmitLogin;
188
+ }
189
+
190
+ const LoginForm: FC<LoginFormProps> = ({ onSuccess, children }) => {
191
+ return (
192
+ <LoginPaperForm onSuccess={onSuccess}>
193
+ <Box px={2}>
194
+ {children}
195
+ <SecureLoginText />
196
+ <LoginFormBase name="page-form" columnCount={1} />
197
+ </Box>
198
+ <FormDialogActions
199
+ removeCancelButton={true}
200
+ gridProps={{ mt:3, mb:1,px:2 }}
201
+ submitProps={{
202
+ altIcon: <AltIcon />,
203
+ children: "Log In",
204
+ maxAttempts: 5,
205
+ }}
206
+ />
207
+ </LoginPaperForm>
208
+ );
209
+ };
210
+
211
+ export default LoginForm;
212
+
213
+ const SecureLoginText: FC<TypographyProps> = (props) => {
214
+ const typographyProps = merge(
215
+ {
216
+ component: "h1",
217
+ variant: "h5",
218
+ sx: { marginBottom: "20px" },
219
+ },
220
+ props,
221
+ );
222
+ return <Typography {...typographyProps}>Secure Login</Typography>;
223
+ };
224
+
225
+ type LoginPaperFormProps = PropsWithChildren & {
226
+ onSuccess?: SubmitLogin;
227
+ };
228
+
229
+ const LoginPaperForm: FC<LoginPaperFormProps> = ({ children, onSuccess }) => {
230
+ return (
231
+ <FormDialogProvider>
232
+ <PaperForm
233
+ formProps={{
234
+ defaultValues: defaultLoginFormValues,
235
+ onSuccess,
236
+ onError: devLog("Form Errors"),
237
+ }}
238
+ elevation={3}
239
+ sx={{
240
+ padding: "20px",
241
+ marginTop: "50px",
242
+ textAlign: "center",
243
+ }}
244
+ >
245
+ {children}
246
+ </PaperForm>
247
+ </FormDialogProvider>
248
+ );
249
+ };
250
+
251
+ ```
252
+ ```tsx
253
+ // LoginPage.tsx
254
+ import { useCallback, useEffect, useState, type FC, type PropsWithChildren } from "react";
255
+ import { Container, IconButton } from "@mui/material";
256
+ import { useUser } from "@features";
257
+ import { useDialog } from "@chris-c-brine/form-dialog";
258
+ import { useForm, type SubmitHandler } from "react-hook-form-mui";
259
+ import { toast } from "react-toastify";
260
+ import LoginDialog from "./components/dialogs/LoginDialog";
261
+ import LoginForm from "./components/forms/LoginForm";
262
+ import { Lock as LockIcon } from "@mui/icons-material";
263
+
264
+ const defaultLoginFormValues = { username: "", password: "" };
265
+ type SubmitLogin = SubmitHandler<typeof defaultLoginFormValues>;
266
+ const LoginPage: FC = () => {
267
+ const { dialogProps, closeDialog, openDialog } = useDialog();
268
+ const { setUser } = useUser();
269
+ const [showDialog, setShowDialog] = useState(dialogProps.open);
270
+
271
+ useEffect(() => {
272
+ if (!showDialog && dialogProps.open) {
273
+ setShowDialog(true);
274
+ }
275
+ }, [dialogProps.open, showDialog]);
276
+
277
+ const formContext = useForm({ defaultValues: defaultLoginFormValues });
278
+ const onSuccess: SubmitLogin = useCallback(
279
+ (data, event) => {
280
+ event?.preventDefault(); // Stop default form submit
281
+ formContext.reset(); // Reset form
282
+ setUser({ name: data.username, isActive: true }); // Update User (and/or other business logic)
283
+ closeDialog(); // Close Dialog
284
+ toast.success("Error Dialog Test!"); // Signal success beyond just closing the dialog
285
+ },
286
+ [formContext, setUser, closeDialog],
287
+ );
288
+
289
+ return (
290
+ <LoginFormContainer>
291
+ <LoginForm onSuccess={onSuccess}>
292
+ <IconButton color="primary" onClick={openDialog} sx={{ py: 1 }}>
293
+ <LockIcon sx={{ fontSize: 50 }} />
294
+ </IconButton>
295
+ </LoginForm>
296
+ {showDialog && (
297
+ <LoginDialog dialogProps={dialogProps} handleSubmit={onSuccess} onClose={undefined} />
298
+ )}
299
+ </LoginFormContainer>
300
+ );
301
+ };
302
+
303
+ export default LoginPage;
304
+
305
+ const LoginFormContainer: FC<PropsWithChildren> = ({ children }) => (
306
+ <Container
307
+ component="main"
308
+ maxWidth={"xs"}
309
+ sx={{
310
+ display: "flex",
311
+ alignItems: "center",
312
+ justifyContent: "center",
313
+ height: "85vh",
314
+ overflow: "hidden",
315
+ animation: "fadeIn 1s ease-in-out",
316
+ "@keyframes fadeIn": {
317
+ from: { opacity: 0 },
318
+ to: { opacity: 1 },
319
+ },
320
+ }}
321
+ >
322
+ {children}
323
+ </Container>
324
+ );
325
+ ```
@@ -0,0 +1,12 @@
1
+ import { type GridProps } from "@mui/material";
2
+ import { type FC, type ReactNode } from "react";
3
+ export type AutoGridProps = Omit<GridProps, "container" | "children"> & {
4
+ components?: ReactNode[];
5
+ columnCount?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
6
+ };
7
+ /**
8
+ * Dev Note:
9
+ * Be careful of transferring keys of children to the wrapper, Grid.
10
+ * If not done correctly, it will cause React to discard the old tree and remount children components
11
+ */
12
+ export declare const AutoGrid: FC<AutoGridProps>;
@@ -0,0 +1,13 @@
1
+ import type { FC, ReactNode } from "react";
2
+ import { type BlackoutDialogProps } from "./BlackoutDialog";
3
+ import type { DialogContentProps, DialogTitleProps, DialogActionsProps } from "@mui/material";
4
+ export type BaseDialogProps = Omit<BlackoutDialogProps, "children" | "title" | "content"> & {
5
+ title?: ReactNode;
6
+ titleProps?: DialogTitleProps;
7
+ children?: ReactNode;
8
+ contentProps?: DialogContentProps;
9
+ actions?: ReactNode;
10
+ actionsProps?: DialogActionsProps;
11
+ closeButton?: ReactNode;
12
+ };
13
+ export declare const BaseDialog: FC<BaseDialogProps>;
@@ -0,0 +1,23 @@
1
+ import { type DialogProps } from "@mui/material";
2
+ import { type FC, type PropsWithChildren } from "react";
3
+ export type BlackoutDialogProps = DialogProps & Partial<PropsWithChildren> & {
4
+ /**
5
+ * An optional unique string identifier
6
+ * @default 'blackout-dialog'
7
+ */
8
+ id?: string;
9
+ /**
10
+ * Whether the dialog is currently visible.
11
+ * @default false
12
+ */
13
+ open: boolean;
14
+ /**
15
+ * Whether to apply a black overlay behind the dialog.
16
+ * @default false
17
+ */
18
+ blackout?: boolean;
19
+ };
20
+ /**
21
+ * A component for rendering a modal dialog with an optional blackout effect.
22
+ */
23
+ export declare const BlackoutDialog: FC<BlackoutDialogProps>;
@@ -0,0 +1,11 @@
1
+ import { type BaseDialogProps } from "./BaseDialog";
2
+ import { type FieldValues, type FormContainerProps } from "react-hook-form-mui";
3
+ /**
4
+ * Props for the FormDialog component. Inherits from BaseDialogProps and adds formProps.
5
+ * @param formProps - Props for the FormContainer component from react-hook-form-mui.
6
+ * @returns The FormDialog component.
7
+ */
8
+ export type FormDialogProps<T extends FieldValues> = Omit<BaseDialogProps, "PaperComponent"> & {
9
+ formProps: FormContainerProps<T>;
10
+ };
11
+ export declare const FormDialog: <T extends FieldValues>({ formProps, children, open, onClose, ...dialogProps }: FormDialogProps<T>) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,15 @@
1
+ import { GridProps } from "@mui/material";
2
+ import type { FC, PropsWithChildren } from "react";
3
+ import { type FormCancelButtonProps } from "./buttons/FormCancelButton";
4
+ import { type FormResetButtonProps } from "./buttons/FormResetButton";
5
+ import { FormSubmitButtonProps } from "./buttons/FormSubmitButton";
6
+ export type FormDialogActionsProps = PropsWithChildren & {
7
+ cancelProps?: FormCancelButtonProps;
8
+ resetProps?: FormResetButtonProps;
9
+ submitProps?: FormSubmitButtonProps;
10
+ variant?: "icon" | "text" | "iconText";
11
+ removeCancelButton?: boolean;
12
+ removeResetButton?: boolean;
13
+ gridProps?: GridProps;
14
+ };
15
+ export declare const FormDialogActions: FC<FormDialogActionsProps>;
@@ -0,0 +1,2 @@
1
+ import type { FC } from "react";
2
+ export declare const GridSpacer: FC;
@@ -0,0 +1,6 @@
1
+ import { type PaperProps } from "@mui/material";
2
+ import { type FieldValues, type FormContainerProps } from "react-hook-form-mui";
3
+ export type PaperFormProps<T extends FieldValues> = PaperProps & {
4
+ formProps: FormContainerProps<T>;
5
+ };
6
+ export declare const PaperForm: <T extends FieldValues>({ children, formProps, ...paperProps }: PaperFormProps<T>) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,5 @@
1
+ import type { FC, PropsWithChildren } from "react";
2
+ export interface PersistFormProps extends PropsWithChildren {
3
+ formName: string;
4
+ }
5
+ export declare const PersistForm: FC<PersistFormProps>;
@@ -0,0 +1,5 @@
1
+ import { type ButtonProps } from "@mui/material";
2
+ export type FormCancelButtonProps = Omit<ButtonProps, "onClick"> & {
3
+ keepCount?: boolean;
4
+ };
5
+ export declare const FormCancelButton: import("react").NamedExoticComponent<object>;
@@ -0,0 +1,6 @@
1
+ import { type ButtonProps } from "@mui/material";
2
+ export type FormResetButtonProps = Omit<ButtonProps, "onClick"> & {
3
+ keepCount?: boolean;
4
+ formKey?: string;
5
+ };
6
+ export declare const FormResetButton: import("react").NamedExoticComponent<object>;
@@ -0,0 +1,9 @@
1
+ import { type LoadingButtonProps } from "./LoadingButton";
2
+ export type FormSubmitButtonProps = Omit<LoadingButtonProps, "onClick"> & {
3
+ showAttempts?: boolean;
4
+ maxAttempts?: number;
5
+ };
6
+ /**
7
+ * Form Submit Button
8
+ */
9
+ export declare const FormSubmitButton: import("react").NamedExoticComponent<FormSubmitButtonProps>;
@@ -0,0 +1,8 @@
1
+ import { type ButtonProps } from "@mui/material";
2
+ import type { ReactNode } from "react";
3
+ export type LoadingButtonProps = ButtonProps & {
4
+ loading?: boolean;
5
+ /** The icon displayed when not loading */
6
+ altIcon?: ReactNode;
7
+ };
8
+ export declare const LoadingButton: ({ children, loading, altIcon, ...props }: LoadingButtonProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,13 @@
1
+ import type { FC, ReactNode } from "react";
2
+ import { type BlackoutDialogProps } from "./BlackoutDialog";
3
+ import type { DialogContentProps, DialogTitleProps, DialogActionsProps } from "@mui/material";
4
+ export type BaseDialogProps = Omit<BlackoutDialogProps, "children" | "title" | "content"> & {
5
+ title?: ReactNode;
6
+ titleProps?: DialogTitleProps;
7
+ children?: ReactNode;
8
+ contentProps?: DialogContentProps;
9
+ actions?: ReactNode;
10
+ actionsProps?: DialogActionsProps;
11
+ closeButton?: ReactNode;
12
+ };
13
+ export declare const BaseDialog: FC<BaseDialogProps>;
@@ -0,0 +1,23 @@
1
+ import { type DialogProps } from "@mui/material";
2
+ import { type FC, type PropsWithChildren } from "react";
3
+ export type BlackoutDialogProps = DialogProps & Partial<PropsWithChildren> & {
4
+ /**
5
+ * An optional unique string identifier
6
+ * @default 'blackout-dialog'
7
+ */
8
+ id?: string;
9
+ /**
10
+ * Whether the dialog is currently visible.
11
+ * @default false
12
+ */
13
+ open: boolean;
14
+ /**
15
+ * Whether to apply a black overlay behind the dialog.
16
+ * @default false
17
+ */
18
+ blackout?: boolean;
19
+ };
20
+ /**
21
+ * A component for rendering a modal dialog with an optional blackout effect.
22
+ */
23
+ export declare const BlackoutDialog: FC<BlackoutDialogProps>;
@@ -0,0 +1,11 @@
1
+ import { type BaseDialogProps } from "./BaseDialog";
2
+ import { type FieldValues, type FormContainerProps } from "react-hook-form-mui";
3
+ /**
4
+ * Props for the FormDialog component. Inherits from BaseDialogProps and adds formProps.
5
+ * @param formProps - Props for the FormContainer component from react-hook-form-mui.
6
+ * @returns The FormDialog component.
7
+ */
8
+ export type FormDialogProps<T extends FieldValues> = Omit<BaseDialogProps, "PaperComponent"> & {
9
+ formProps: FormContainerProps<T>;
10
+ };
11
+ export declare const FormDialog: <T extends FieldValues>({ formProps, children, open, onClose, ...dialogProps }: FormDialogProps<T>) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,15 @@
1
+ import { GridProps } from "@mui/material";
2
+ import type { FC, PropsWithChildren } from "react";
3
+ import { type FormCancelButtonProps } from "../buttons/FormCancelButton";
4
+ import { type FormResetButtonProps } from "../buttons/FormResetButton";
5
+ import { FormSubmitButtonProps } from "../buttons/FormSubmitButton";
6
+ export type FormDialogActionsProps = PropsWithChildren & {
7
+ cancelProps?: FormCancelButtonProps;
8
+ resetProps?: FormResetButtonProps;
9
+ submitProps?: FormSubmitButtonProps;
10
+ variant?: "icon" | "text" | "iconText";
11
+ removeCancelButton?: boolean;
12
+ removeResetButton?: boolean;
13
+ gridProps?: GridProps;
14
+ };
15
+ export declare const FormDialogActions: FC<FormDialogActionsProps>;
@@ -0,0 +1,6 @@
1
+ import { type PaperProps } from "@mui/material";
2
+ import { type FieldValues, type FormContainerProps } from "react-hook-form-mui";
3
+ export type PaperFormProps<T extends FieldValues> = PaperProps & {
4
+ formProps: FormContainerProps<T>;
5
+ };
6
+ export declare const PaperForm: <T extends FieldValues>({ children, formProps, ...paperProps }: PaperFormProps<T>) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,5 @@
1
+ import type { FC, PropsWithChildren } from "react";
2
+ export interface PersistFormProps extends PropsWithChildren {
3
+ formName: string;
4
+ }
5
+ export declare const PersistForm: FC<PersistFormProps>;
@@ -0,0 +1,10 @@
1
+ export * from "./dialogs/FormDialog";
2
+ export * from "./dialogs/BaseDialog";
3
+ export * from "./dialogs/BlackoutDialog";
4
+ export * from "./forms/PaperForm";
5
+ export * from "./forms/PersistForm";
6
+ export * from "./buttons/FormCancelButton";
7
+ export * from "./buttons/FormSubmitButton";
8
+ export * from "./buttons/FormResetButton";
9
+ export * from "./dialogs/FormDialogActions";
10
+ export * from "./AutoGrid";
@@ -0,0 +1,5 @@
1
+ export * from "./useFormDialog";
2
+ export * from "./useMaxAttempts";
3
+ export * from "./usePersistedForm";
4
+ export * from "./useOnMount";
5
+ export * from "./useDialog";
@@ -0,0 +1,12 @@
1
+ export interface UseDialogProps {
2
+ defaultOpen: boolean;
3
+ }
4
+ export declare const useDialog: (props?: UseDialogProps) => {
5
+ closeDialog: () => void;
6
+ openDialog: () => void;
7
+ dialogProps: {
8
+ open: boolean;
9
+ onClose: () => void;
10
+ keepMounted: boolean;
11
+ };
12
+ };
@@ -0,0 +1 @@
1
+ export declare const useFormDialog: () => import("../state/FormDialogContext").FormDialogContextType;
@@ -0,0 +1,5 @@
1
+ type UseMaxAttemptProps = {
2
+ maxAttempts?: number;
3
+ };
4
+ export declare const useMaxAttempts: ({ maxAttempts }: UseMaxAttemptProps) => void;
5
+ export {};
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Runs a provided callback function once on the first component mount.
3
+ *
4
+ * @param callback - The function to run on first mount.
5
+ */
6
+ export declare function useOnMount(callback: () => void): void;
@@ -0,0 +1,7 @@
1
+ export interface PersistedFormProviderProps {
2
+ /**
3
+ * A unique key for the form
4
+ */
5
+ formName: string | undefined;
6
+ }
7
+ export declare const usePersistedForm: ({ formName }: PersistedFormProviderProps) => void;
@@ -0,0 +1,4 @@
1
+ export * from "./components";
2
+ export * from "./utils";
3
+ export { usePersistedForm, useFormDialog, useDialog } from "./hooks";
4
+ export { FormDialogProvider } from "./state/FormDialogProvider";