@chris-c-brine/form-dialog 1.0.5 → 1.1.0
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 +170 -162
- package/dist/components/buttons/FormResetButton.d.ts +0 -4
- package/dist/components/buttons/FormSubmitButton.d.ts +1 -4
- package/dist/components/dialogs/BaseDialog.d.ts +5 -26
- package/dist/components/dialogs/BlackoutDialog.d.ts +2 -2
- package/dist/components/dialogs/FormDialog.d.ts +7 -9
- package/dist/components/dialogs/FormDialogActions.d.ts +2 -2
- package/dist/components/forms/PaperForm.d.ts +14 -6
- package/dist/components/forms/PersistForm.d.ts +2 -2
- package/dist/components/index.d.ts +1 -0
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/useDialog.d.ts +18 -12
- package/dist/hooks/useFormDialog.d.ts +1 -1
- package/dist/hooks/usePersistForm.d.ts +29 -0
- package/dist/index.d.ts +1 -2
- package/dist/index.esm.js +207 -234
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +207 -234
- package/dist/index.js.map +1 -1
- package/dist/utils/ThemeBridge.d.ts +0 -1
- package/dist/utils/applyDefaultFormDialogProps.d.ts +29 -29
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/utils.types.d.ts +15 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -40,36 +40,82 @@ This package has the following peer dependencies that need to be installed in yo
|
|
|
40
40
|
|
|
41
41
|
## Login Form Usage Example
|
|
42
42
|
|
|
43
|
+
```tsx
|
|
44
|
+
// LoginPage.tsx
|
|
45
|
+
import { type FC } from "react";
|
|
46
|
+
import { Container, IconButton } from "@mui/material";
|
|
47
|
+
import { useDialog } from "@chris-c-brine/form-dialog";
|
|
48
|
+
import LoginForm from "./components/forms/LoginForm";
|
|
49
|
+
import { Lock as LockIcon } from "@mui/icons-material";
|
|
50
|
+
import { LoginDialog } from "./LoginDialog";
|
|
51
|
+
|
|
52
|
+
const LoginPage: FC = () => {
|
|
53
|
+
const { dialogProps, openDialog } = useDialog();
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<Container
|
|
57
|
+
component="main"
|
|
58
|
+
maxWidth={"xs"}
|
|
59
|
+
sx={{
|
|
60
|
+
display: "flex",
|
|
61
|
+
alignItems: "center",
|
|
62
|
+
justifyContent: "center",
|
|
63
|
+
height: "85vh",
|
|
64
|
+
overflow: "hidden",
|
|
65
|
+
animation: "fadeIn 1s ease-in-out",
|
|
66
|
+
"@keyframes fadeIn": {
|
|
67
|
+
from: { opacity: 0 },
|
|
68
|
+
to: { opacity: 1 },
|
|
69
|
+
},
|
|
70
|
+
}}
|
|
71
|
+
>
|
|
72
|
+
<LoginForm>
|
|
73
|
+
<IconButton color="primary" onClick={openDialog} sx={{ py: 1 }}>
|
|
74
|
+
<LockIcon sx={{ fontSize: 50 }} />
|
|
75
|
+
</IconButton>
|
|
76
|
+
</LoginForm>
|
|
77
|
+
<LoginDialog dialogProps={dialogProps} />
|
|
78
|
+
</Container>
|
|
79
|
+
);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export default LoginPage;
|
|
83
|
+
```
|
|
84
|
+
```tsx
|
|
85
|
+
// LoginPageConstants.ts
|
|
86
|
+
import type { SubmitHandler } from "react-hook-form";
|
|
87
|
+
|
|
88
|
+
export const defaultLoginFormValues = { username: "", password: "" };
|
|
89
|
+
export type LoginFormValues = typeof defaultLoginFormValues;
|
|
90
|
+
```
|
|
43
91
|
```tsx
|
|
44
92
|
// LoginFormBase.tsx
|
|
45
|
-
import {
|
|
46
|
-
TextFieldElement,
|
|
47
|
-
PasswordElement,
|
|
48
|
-
type PasswordElementProps,
|
|
49
|
-
useFormContext,
|
|
50
|
-
} from "react-hook-form-mui";
|
|
93
|
+
import { TextFieldElement, PasswordElement, type PasswordElementProps, useFormContext} from "react-hook-form-mui";
|
|
51
94
|
import { memo, useEffect } from "react";
|
|
52
|
-
import { useFormDialog,
|
|
95
|
+
import { useFormDialog, AutoGrid, type AutoGridProps } from "@chris-c-brine/form-dialog";
|
|
53
96
|
|
|
54
|
-
|
|
55
|
-
|
|
97
|
+
/**
|
|
98
|
+
* Login Form
|
|
99
|
+
*/
|
|
100
|
+
export type NameProp = {
|
|
101
|
+
name?: string;
|
|
102
|
+
};
|
|
56
103
|
|
|
104
|
+
export type LoginFormProps = NameProp & Pick<AutoGridProps, "columnCount">;
|
|
57
105
|
const LoginFormBase = memo(function ({ name, columnCount = 1 }: LoginFormProps) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
/>
|
|
72
|
-
);
|
|
106
|
+
const { disabled } = useFormDialog();
|
|
107
|
+
|
|
108
|
+
return (
|
|
109
|
+
<AutoGrid
|
|
110
|
+
columnCount={columnCount}
|
|
111
|
+
columnSpacing={2}
|
|
112
|
+
rowSpacing={1}
|
|
113
|
+
components={[
|
|
114
|
+
<UserName key={`${name}-username`} disabled={disabled} />,
|
|
115
|
+
<Password key={`${name}-password`} disabled={disabled} />,
|
|
116
|
+
]}
|
|
117
|
+
/>
|
|
118
|
+
);
|
|
73
119
|
});
|
|
74
120
|
|
|
75
121
|
LoginFormBase.displayName = "LoginForm";
|
|
@@ -80,37 +126,36 @@ export default LoginFormBase;
|
|
|
80
126
|
* Inputs
|
|
81
127
|
*/
|
|
82
128
|
const UserName = ({ disabled }: Pick<PasswordElementProps, "disabled">) => (
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
129
|
+
<TextFieldElement
|
|
130
|
+
name="username"
|
|
131
|
+
label="Username"
|
|
132
|
+
required
|
|
133
|
+
autoFocus
|
|
134
|
+
autoComplete="off"
|
|
135
|
+
fullWidth
|
|
136
|
+
margin={"dense"}
|
|
137
|
+
size={"medium"}
|
|
138
|
+
disabled={disabled}
|
|
139
|
+
slotProps={{
|
|
140
|
+
inputLabel: { shrink: true },
|
|
141
|
+
}}
|
|
142
|
+
/>
|
|
97
143
|
);
|
|
98
|
-
|
|
99
144
|
UserName.displayName = "UserName";
|
|
100
145
|
|
|
101
|
-
const Password =
|
|
146
|
+
const Password = ({ disabled }: Pick<PasswordElementProps, "disabled">) => {
|
|
102
147
|
const { setValue, getValues } = useFormContext();
|
|
103
148
|
const password = getValues("password");
|
|
104
149
|
|
|
105
150
|
useEffect(() => {
|
|
106
151
|
if (disabled && password !== "") {
|
|
107
|
-
setValue("
|
|
152
|
+
setValue("disabledPassword", "");
|
|
108
153
|
}
|
|
109
154
|
}, [disabled, setValue, password]);
|
|
110
155
|
|
|
111
156
|
return (
|
|
112
157
|
<PasswordElement
|
|
113
|
-
name={"
|
|
158
|
+
name={"password"}
|
|
114
159
|
label={"Password"}
|
|
115
160
|
fullWidth
|
|
116
161
|
required
|
|
@@ -125,71 +170,29 @@ const Password = function ({ disabled }: Pick<PasswordElementProps, "disabled">)
|
|
|
125
170
|
/>
|
|
126
171
|
);
|
|
127
172
|
};
|
|
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
173
|
|
|
152
|
-
|
|
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;
|
|
174
|
+
Password.displayName = "Password";
|
|
172
175
|
```
|
|
173
176
|
```tsx
|
|
174
177
|
// LoginForm.tsx
|
|
175
178
|
import { Lock as LockIcon } from "@mui/icons-material";
|
|
176
179
|
import { Box, Typography, type TypographyProps } from "@mui/material";
|
|
177
|
-
import { type SubmitLogin, defaultLoginFormValues } from "@pages/LoginPage/LoginPageConstants";
|
|
178
|
-
import { devLog } from "@utils";
|
|
179
180
|
import { merge } from "lodash";
|
|
180
|
-
import
|
|
181
|
-
import LoginFormBase from "./LoginFormBase";
|
|
181
|
+
import { FC, PropsWithChildren, useCallback, useMemo } from "react";
|
|
182
182
|
import { FormDialogActions, FormDialogProvider, PaperForm } from "@chris-c-brine/form-dialog";
|
|
183
|
+
import { SubmitHandler, useForm } from "react-hook-form-mui";
|
|
184
|
+
import { defaultLoginFormValues, LoginFormValues } from "./LoginPageConstants";
|
|
185
|
+
import LoginFormBase from "./LoginFormBase";
|
|
186
|
+
import { globalErrorAtom, useUser } from "@features";
|
|
187
|
+
import { useSetAtom } from "jotai/index";
|
|
188
|
+
import { Person as PersonIcon } from "@mui/icons-material";
|
|
183
189
|
|
|
184
190
|
const AltIcon = () => <LockIcon sx={{ mr: 1, fontSize: 20 }} />;
|
|
185
191
|
|
|
186
|
-
|
|
187
|
-
onSuccess: SubmitLogin;
|
|
188
|
-
}
|
|
192
|
+
export const LoginForm: FC<PropsWithChildren> = ({ children }) => {
|
|
189
193
|
|
|
190
|
-
const LoginForm: FC<LoginFormProps> = ({ onSuccess, children }) => {
|
|
191
194
|
return (
|
|
192
|
-
<LoginPaperForm
|
|
195
|
+
<LoginPaperForm>
|
|
193
196
|
<Box px={2}>
|
|
194
197
|
{children}
|
|
195
198
|
<SecureLoginText />
|
|
@@ -208,8 +211,6 @@ const LoginForm: FC<LoginFormProps> = ({ onSuccess, children }) => {
|
|
|
208
211
|
);
|
|
209
212
|
};
|
|
210
213
|
|
|
211
|
-
export default LoginForm;
|
|
212
|
-
|
|
213
214
|
const SecureLoginText: FC<TypographyProps> = (props) => {
|
|
214
215
|
const typographyProps = merge(
|
|
215
216
|
{
|
|
@@ -222,18 +223,38 @@ const SecureLoginText: FC<TypographyProps> = (props) => {
|
|
|
222
223
|
return <Typography {...typographyProps}>Secure Login</Typography>;
|
|
223
224
|
};
|
|
224
225
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
};
|
|
226
|
+
const LoginPaperForm: FC<PropsWithChildren> = ({ children }) => {
|
|
227
|
+
const formContext = useForm({defaultValues: defaultLoginFormValues});
|
|
228
|
+
const { setUser } = useUser();
|
|
229
|
+
const setError = useSetAtom(globalErrorAtom);
|
|
230
|
+
const reset = useMemo(() => formContext.reset, [formContext?.reset]);
|
|
231
|
+
|
|
232
|
+
const onSuccess: SubmitHandler<LoginFormValues> = useCallback(
|
|
233
|
+
(data, event) => {
|
|
234
|
+
event?.preventDefault(); // Stop default html form submit
|
|
235
|
+
event?.stopPropagation(); // STOP!!!!!
|
|
236
|
+
|
|
237
|
+
setUser({ name: data.username, isActive: true }); // Update User (and/or other business logic)
|
|
238
|
+
reset(); // reset form
|
|
239
|
+
setError({ // Signal Success!
|
|
240
|
+
message: <>Hello {data.username}!</>,
|
|
241
|
+
title: "Successful Login!",
|
|
242
|
+
severity: "success",
|
|
243
|
+
icon: <PersonIcon sx={{ fontSize: 35 }} />,
|
|
244
|
+
});
|
|
245
|
+
}, [setUser, setError, reset]);
|
|
228
246
|
|
|
229
|
-
const LoginPaperForm: FC<LoginPaperFormProps> = ({ children, onSuccess }) => {
|
|
230
247
|
return (
|
|
231
248
|
<FormDialogProvider>
|
|
232
249
|
<PaperForm
|
|
250
|
+
persistKey={'login-page-form'}
|
|
233
251
|
formProps={{
|
|
234
|
-
|
|
252
|
+
formContext,
|
|
235
253
|
onSuccess,
|
|
236
|
-
onError:
|
|
254
|
+
onError: (errors, event) => {
|
|
255
|
+
event?.preventDefault();
|
|
256
|
+
console.log(errors)
|
|
257
|
+
},
|
|
237
258
|
}}
|
|
238
259
|
elevation={3}
|
|
239
260
|
sx={{
|
|
@@ -247,79 +268,66 @@ const LoginPaperForm: FC<LoginPaperFormProps> = ({ children, onSuccess }) => {
|
|
|
247
268
|
</FormDialogProvider>
|
|
248
269
|
);
|
|
249
270
|
};
|
|
250
|
-
|
|
251
271
|
```
|
|
252
272
|
```tsx
|
|
253
|
-
//
|
|
254
|
-
import {
|
|
255
|
-
import {
|
|
256
|
-
import
|
|
257
|
-
import {
|
|
258
|
-
import {
|
|
259
|
-
import {
|
|
260
|
-
import
|
|
261
|
-
import
|
|
262
|
-
import { Lock as LockIcon } from "@mui/icons-material";
|
|
273
|
+
// LoginDialog.tsx
|
|
274
|
+
import { useDialog, FormDialog, FormDialogActions } from "@chris-c-brine/form-dialog";
|
|
275
|
+
import { memo, useCallback, useMemo } from "react";
|
|
276
|
+
import LoginFormBase from "./LoginFormBase";
|
|
277
|
+
import { defaultLoginFormValues, LoginFormValues } from "./LoginPageConstants";
|
|
278
|
+
import { SubmitHandler, useForm } from "react-hook-form-mui";
|
|
279
|
+
import { globalErrorAtom, useUser } from "@features";
|
|
280
|
+
import { useSetAtom } from "jotai/index";
|
|
281
|
+
import { Person as PersonIcon } from "@mui/icons-material";
|
|
263
282
|
|
|
264
|
-
const
|
|
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);
|
|
283
|
+
const formKey = "dialog-login-form";
|
|
270
284
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
}
|
|
275
|
-
}, [dialogProps.open, showDialog]);
|
|
285
|
+
export type LoginDialogProps = {
|
|
286
|
+
dialogProps: ReturnType<typeof useDialog>["dialogProps"];
|
|
287
|
+
};
|
|
276
288
|
|
|
289
|
+
export const LoginDialog = memo(function ({ dialogProps }: LoginDialogProps) {
|
|
290
|
+
const setError = useSetAtom(globalErrorAtom);
|
|
291
|
+
const { setUser } = useUser();
|
|
277
292
|
const formContext = useForm({ defaultValues: defaultLoginFormValues });
|
|
278
|
-
|
|
293
|
+
|
|
294
|
+
const reset = useMemo(() => formContext.reset, [formContext?.reset]);
|
|
295
|
+
|
|
296
|
+
const onSuccess: SubmitHandler<LoginFormValues> = useCallback(
|
|
279
297
|
(data, event) => {
|
|
280
|
-
event?.preventDefault();
|
|
281
|
-
|
|
298
|
+
event?.preventDefault();
|
|
299
|
+
event?.stopPropagation();
|
|
300
|
+
|
|
301
|
+
console.log(event);
|
|
282
302
|
setUser({ name: data.username, isActive: true }); // Update User (and/or other business logic)
|
|
283
|
-
|
|
284
|
-
|
|
303
|
+
reset(); // reset form
|
|
304
|
+
setError({
|
|
305
|
+
// Signal Success!
|
|
306
|
+
message: <>Hello {data.username}!</>,
|
|
307
|
+
title: "Successful Login!",
|
|
308
|
+
severity: "success",
|
|
309
|
+
icon: <PersonIcon sx={{ fontSize: 35 }} />,
|
|
310
|
+
});
|
|
311
|
+
dialogProps?.onClose();
|
|
285
312
|
},
|
|
286
|
-
[
|
|
313
|
+
[setUser, setError, dialogProps, reset],
|
|
287
314
|
);
|
|
288
315
|
|
|
289
316
|
return (
|
|
290
|
-
<
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
{
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
</
|
|
317
|
+
<FormDialog
|
|
318
|
+
{...dialogProps}
|
|
319
|
+
persistKey={formKey}
|
|
320
|
+
formProps={{ onSuccess, formContext }}
|
|
321
|
+
title={"Basic Persist Form Dialog Test"}
|
|
322
|
+
titleProps={{ variant: "h5", textAlign: "center" }}
|
|
323
|
+
actions={<FormDialogActions resetProps={{ formKey }} submitProps={{ maxAttempts: 3 }} />}
|
|
324
|
+
>
|
|
325
|
+
<LoginFormBase columnCount={2} />
|
|
326
|
+
</FormDialog>
|
|
300
327
|
);
|
|
301
|
-
};
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
LoginDialog.displayName = "LoginDialog";
|
|
302
331
|
|
|
303
|
-
export default LoginPage;
|
|
304
332
|
|
|
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
333
|
```
|
|
@@ -31,10 +31,6 @@ export type FormResetButtonProps = Omit<ButtonProps, "onClick"> & {
|
|
|
31
31
|
* - Form-wide disabled state from FormDialogContext
|
|
32
32
|
*
|
|
33
33
|
* @example
|
|
34
|
-
* // Basic usage
|
|
35
|
-
* <FormResetButton />
|
|
36
|
-
*
|
|
37
|
-
* @example
|
|
38
34
|
* // With persistence integration
|
|
39
35
|
* <FormResetButton formKey="user-profile-form" />
|
|
40
36
|
*
|
|
@@ -14,7 +14,7 @@ export type FormSubmitButtonProps = Omit<LoadingButtonProps, "onClick"> & {
|
|
|
14
14
|
maxAttempts?: number;
|
|
15
15
|
};
|
|
16
16
|
/**
|
|
17
|
-
* A submit button for forms with loading state, attempt tracking and form context awareness
|
|
17
|
+
* A "submit button" for forms with loading state, attempt tracking and form context awareness
|
|
18
18
|
*
|
|
19
19
|
* This component extends the LoadingButton with form-specific features:
|
|
20
20
|
* - Automatically displays loading state during form submission
|
|
@@ -28,9 +28,6 @@ export type FormSubmitButtonProps = Omit<LoadingButtonProps, "onClick"> & {
|
|
|
28
28
|
* - Explicit-disabled prop
|
|
29
29
|
* - Form-wide disabled state from FormDialogContext
|
|
30
30
|
*
|
|
31
|
-
* @example
|
|
32
|
-
* // Basic usage
|
|
33
|
-
* <FormSubmitButton />
|
|
34
31
|
*
|
|
35
32
|
* @example
|
|
36
33
|
* // With custom text and max attempts
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { FC, ReactNode } from "react";
|
|
2
2
|
import { type BlackoutDialogProps } from "./BlackoutDialog";
|
|
3
3
|
import type { DialogContentProps, DialogTitleProps, DialogActionsProps } from "@mui/material";
|
|
4
|
-
export type BaseDialogProps =
|
|
4
|
+
export type BaseDialogProps = BlackoutDialogProps & {
|
|
5
5
|
/**
|
|
6
6
|
* Title content for the dialog
|
|
7
7
|
* When provided, renders a DialogTitle component
|
|
@@ -9,17 +9,12 @@ export type BaseDialogProps = Omit<BlackoutDialogProps, "children" | "title" | "
|
|
|
9
9
|
title?: ReactNode;
|
|
10
10
|
/**
|
|
11
11
|
* Props passed to the DialogTitle component
|
|
12
|
-
* Only applied when title is provided
|
|
12
|
+
* Only applied when the title is provided
|
|
13
13
|
*/
|
|
14
14
|
titleProps?: DialogTitleProps;
|
|
15
|
-
/**
|
|
16
|
-
* Main content of the dialog
|
|
17
|
-
* When provided, renders a DialogContent component
|
|
18
|
-
*/
|
|
19
|
-
children?: ReactNode;
|
|
20
15
|
/**
|
|
21
16
|
* Props passed to the DialogContent component
|
|
22
|
-
* Only applied when children
|
|
17
|
+
* Only applied when children are provided
|
|
23
18
|
*/
|
|
24
19
|
contentProps?: DialogContentProps;
|
|
25
20
|
/**
|
|
@@ -29,7 +24,7 @@ export type BaseDialogProps = Omit<BlackoutDialogProps, "children" | "title" | "
|
|
|
29
24
|
actions?: ReactNode;
|
|
30
25
|
/**
|
|
31
26
|
* Props passed to the DialogActions component
|
|
32
|
-
* Only applied when actions
|
|
27
|
+
* Only applied when actions are provided
|
|
33
28
|
*/
|
|
34
29
|
actionsProps?: DialogActionsProps;
|
|
35
30
|
/**
|
|
@@ -57,27 +52,11 @@ export type BaseDialogProps = Omit<BlackoutDialogProps, "children" | "title" | "
|
|
|
57
52
|
* consistent styling and behavior.
|
|
58
53
|
*
|
|
59
54
|
* @example
|
|
60
|
-
* // Basic usage with all sections
|
|
61
|
-
* <BaseDialog
|
|
62
|
-
* open={open}
|
|
63
|
-
* onClose={handleClose}
|
|
64
|
-
* title="Confirmation"
|
|
65
|
-
* actions={
|
|
66
|
-
* <>
|
|
67
|
-
* <Button onClick={handleCancel}>Cancel</Button>
|
|
68
|
-
* <Button onClick={handleConfirm}>Confirm</Button>
|
|
69
|
-
* </>
|
|
70
|
-
* }
|
|
71
|
-
* >
|
|
72
|
-
* Are you sure you want to proceed?
|
|
73
|
-
* </BaseDialog>
|
|
74
|
-
*
|
|
75
|
-
* @example
|
|
76
55
|
* // Customized with section props
|
|
77
56
|
* <BaseDialog
|
|
78
57
|
* open={isOpen}
|
|
79
58
|
* title="Advanced Settings"
|
|
80
|
-
* titleProps={{ sx: {
|
|
59
|
+
* titleProps={{ sx: { backgroundColor: 'primary.main', color: 'white' } }}
|
|
81
60
|
* contentProps={{ sx: { p: 3 } }}
|
|
82
61
|
* actionsProps={{ sx: { justifyContent: 'space-between' } }}
|
|
83
62
|
* actions={<SettingsDialogActions />}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type DialogProps } from "@mui/material";
|
|
2
|
-
import { type FC
|
|
3
|
-
export type BlackoutDialogProps = DialogProps
|
|
2
|
+
import { type FC } from "react";
|
|
3
|
+
export type BlackoutDialogProps = Omit<DialogProps, "title"> & {
|
|
4
4
|
/**
|
|
5
5
|
* An optional unique string identifier
|
|
6
6
|
* @default 'blackout-dialog'
|
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
import { type BaseDialogProps } from "./BaseDialog";
|
|
2
|
-
import {
|
|
2
|
+
import { CommonFormProps } from "../forms/PaperForm";
|
|
3
|
+
import { type FieldValues } from "react-hook-form-mui";
|
|
3
4
|
/**
|
|
4
5
|
* Props for the FormDialog component
|
|
5
6
|
*/
|
|
6
|
-
export type FormDialogProps<T extends FieldValues> = Omit<BaseDialogProps, "PaperComponent"> &
|
|
7
|
-
/**
|
|
8
|
-
* Form methods from useForm hook
|
|
9
|
-
* Establish the form context for child components
|
|
10
|
-
*/
|
|
11
|
-
formProps: FormContainerProps<T>;
|
|
12
|
-
};
|
|
7
|
+
export type FormDialogProps<T extends FieldValues> = Omit<BaseDialogProps, "PaperComponent"> & CommonFormProps<T>;
|
|
13
8
|
/**
|
|
14
9
|
* A dialog component specialized for forms with integrated context providers
|
|
15
10
|
*
|
|
@@ -31,4 +26,7 @@ export type FormDialogProps<T extends FieldValues> = Omit<BaseDialogProps, "Pape
|
|
|
31
26
|
* - useFormDialog() - Access dialog controls and state
|
|
32
27
|
*
|
|
33
28
|
*/
|
|
34
|
-
export declare const FormDialog:
|
|
29
|
+
export declare const FormDialog: {
|
|
30
|
+
<T extends FieldValues>({ formProps, children, open, onClose, persistKey, ...dialogProps }: FormDialogProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
31
|
+
displayName: string;
|
|
32
|
+
};
|
|
@@ -6,7 +6,7 @@ import { FormSubmitButtonProps } from "../buttons/FormSubmitButton";
|
|
|
6
6
|
/**
|
|
7
7
|
* Props for the FormDialogActions component
|
|
8
8
|
*/
|
|
9
|
-
export type FormDialogActionsProps = PropsWithChildren & {
|
|
9
|
+
export type FormDialogActionsProps = Partial<PropsWithChildren> & {
|
|
10
10
|
/**
|
|
11
11
|
* Props to customize the cancel button
|
|
12
12
|
*/
|
|
@@ -16,7 +16,7 @@ export type FormDialogActionsProps = PropsWithChildren & {
|
|
|
16
16
|
*/
|
|
17
17
|
resetProps?: FormResetButtonProps;
|
|
18
18
|
/**
|
|
19
|
-
* Props to customize the submit button
|
|
19
|
+
* Props to customize the "submit button"
|
|
20
20
|
*/
|
|
21
21
|
submitProps?: FormSubmitButtonProps;
|
|
22
22
|
/**
|
|
@@ -1,15 +1,23 @@
|
|
|
1
1
|
import { type PaperProps } from "@mui/material";
|
|
2
2
|
import { type FieldValues, type FormContainerProps } from "react-hook-form-mui";
|
|
3
|
-
|
|
4
|
-
* Props for the PaperForm component
|
|
5
|
-
*/
|
|
6
|
-
export type PaperFormProps<T extends FieldValues> = PaperProps & {
|
|
3
|
+
export type CommonFormProps<T extends FieldValues> = {
|
|
7
4
|
/**
|
|
8
5
|
* Props to configure the form container
|
|
9
|
-
*
|
|
6
|
+
* This includes settings for form state, validation, and submission handling
|
|
10
7
|
*/
|
|
11
8
|
formProps: FormContainerProps<T>;
|
|
9
|
+
/**
|
|
10
|
+
* Optional key to use for form state persistence
|
|
11
|
+
* When provided, the form state will be persisted in
|
|
12
|
+
* session storage with a fallback to local storage (TODO: make configurable)
|
|
13
|
+
* and restored on form reload/mount.
|
|
14
|
+
*/
|
|
15
|
+
persistKey?: string;
|
|
12
16
|
};
|
|
17
|
+
/**
|
|
18
|
+
* Props for the PaperForm component
|
|
19
|
+
*/
|
|
20
|
+
export type PaperFormProps<T extends FieldValues> = PaperProps & CommonFormProps<T>;
|
|
13
21
|
/**
|
|
14
22
|
* A component that combines a Material UI Paper with a form container
|
|
15
23
|
*
|
|
@@ -56,4 +64,4 @@ export type PaperFormProps<T extends FieldValues> = PaperProps & {
|
|
|
56
64
|
*
|
|
57
65
|
* @template T - The type of form values being handled
|
|
58
66
|
*/
|
|
59
|
-
export declare const PaperForm: <T extends FieldValues>({ children, formProps, ...paperProps }: PaperFormProps<T>) => import("react/jsx-runtime").JSX.Element;
|
|
67
|
+
export declare const PaperForm: <T extends FieldValues>({ children, persistKey, formProps, ...paperProps }: PaperFormProps<T>) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { type PropsWithChildren } from "react";
|
|
2
2
|
/**
|
|
3
3
|
* Props for the PersistForm component
|
|
4
4
|
*/
|
|
@@ -50,4 +50,4 @@ export interface PersistFormProps extends PropsWithChildren {
|
|
|
50
50
|
* </PersistForm>
|
|
51
51
|
* </FormDialog>
|
|
52
52
|
*/
|
|
53
|
-
export declare const PersistForm:
|
|
53
|
+
export declare const PersistForm: import("react").NamedExoticComponent<PersistFormProps>;
|
|
@@ -6,6 +6,7 @@ export * from "./forms/PersistForm";
|
|
|
6
6
|
export * from "./buttons/FormCancelButton";
|
|
7
7
|
export * from "./buttons/FormSubmitButton";
|
|
8
8
|
export * from "./buttons/FormResetButton";
|
|
9
|
+
export * from "./buttons/LoadingButton";
|
|
9
10
|
export * from "./dialogs/FormDialogActions";
|
|
10
11
|
export * from "./AutoGrid";
|
|
11
12
|
export * from "./GridSpacer";
|
package/dist/hooks/index.d.ts
CHANGED