@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.
- package/README.md +325 -0
- package/dist/components/AutoGrid.d.ts +12 -0
- package/dist/components/BaseDialog.d.ts +13 -0
- package/dist/components/BlackoutDialog.d.ts +23 -0
- package/dist/components/FormDialog.d.ts +11 -0
- package/dist/components/FormDialogActions.d.ts +15 -0
- package/dist/components/GridSpacer.d.ts +2 -0
- package/dist/components/PaperForm.d.ts +6 -0
- package/dist/components/PersistForm.d.ts +5 -0
- package/dist/components/buttons/FormCancelButton.d.ts +5 -0
- package/dist/components/buttons/FormResetButton.d.ts +6 -0
- package/dist/components/buttons/FormSubmitButton.d.ts +9 -0
- package/dist/components/buttons/LoadingButton.d.ts +8 -0
- package/dist/components/dialogs/BaseDialog.d.ts +13 -0
- package/dist/components/dialogs/BlackoutDialog.d.ts +23 -0
- package/dist/components/dialogs/FormDialog.d.ts +11 -0
- package/dist/components/dialogs/FormDialogActions.d.ts +15 -0
- package/dist/components/forms/PaperForm.d.ts +6 -0
- package/dist/components/forms/PersistForm.d.ts +5 -0
- package/dist/components/index.d.ts +10 -0
- package/dist/hooks/index.d.ts +5 -0
- package/dist/hooks/useDialog.d.ts +12 -0
- package/dist/hooks/useFormDialog.d.ts +1 -0
- package/dist/hooks/useMaxAttempts.d.ts +5 -0
- package/dist/hooks/useOnMount.d.ts +6 -0
- package/dist/hooks/usePersistedForm.d.ts +7 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.esm.js +390 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +390 -0
- package/dist/index.js.map +1 -0
- package/dist/state/FormDialogContext.d.ts +9 -0
- package/dist/state/FormDialogProvider.d.ts +5 -0
- package/dist/state/createFormChangeStore.d.ts +24 -0
- package/dist/utils/ThemeBridge.d.ts +7 -0
- package/dist/utils/applyDefaultFormDialogProps.d.ts +1417 -0
- package/dist/utils/deepCompare.d.ts +16 -0
- package/dist/utils/hasMaxAttempts.d.ts +5 -0
- package/dist/utils/index.d.ts +3 -0
- 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,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,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,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,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;
|
package/dist/index.d.ts
ADDED