From d724f15071fbdeeea84c804af190d31d1676187c Mon Sep 17 00:00:00 2001
From: erfanmoghadasi <97363934+erfanmoghadasi@users.noreply.github.com>
Date: Mon, 11 Mar 2024 14:28:44 +0330
Subject: [PATCH] feat(form): actions (submit & base button) in form (#5)
---
apps/docs/src/app/app.tsx | 108 +++++++++---------
package-lock.json | 96 ++++++++++++++--
package.json | 1 +
.../components/actions/base/actionBase.tsx | 9 ++
.../actions/base/actionBase.types.ts | 6 +
.../src/components/actions/submit/submit.tsx | 25 ++++
.../components/actions/submit/submit.types.ts | 4 +
.../src/components/builder/builder.types.ts | 6 +-
.../src/components/{ => fields}/text/text.tsx | 4 +-
.../{ => fields}/text/text.types.ts | 2 +-
.../components/form/src/types/public.types.ts | 9 +-
.../form/src/utils/selector/selector.tsx | 20 +++-
.../form/src/utils/selector/selector.types.ts | 8 +-
.../src/lib/components/builder/builder.tsx | 9 +-
.../core/src/lib/utils/selector/selector.tsx | 10 +-
15 files changed, 218 insertions(+), 99 deletions(-)
create mode 100644 packages/components/form/src/components/actions/base/actionBase.tsx
create mode 100644 packages/components/form/src/components/actions/base/actionBase.types.ts
create mode 100644 packages/components/form/src/components/actions/submit/submit.tsx
create mode 100644 packages/components/form/src/components/actions/submit/submit.types.ts
rename packages/components/form/src/components/{ => fields}/text/text.tsx (90%)
rename packages/components/form/src/components/{ => fields}/text/text.types.ts (63%)
diff --git a/apps/docs/src/app/app.tsx b/apps/docs/src/app/app.tsx
index 2c28e94..ddc1842 100644
--- a/apps/docs/src/app/app.tsx
+++ b/apps/docs/src/app/app.tsx
@@ -1,15 +1,58 @@
-import { Route, Routes, Link } from 'react-router-dom';
-
-// import { Form } from '@mui-builder/form';
-import { Builder, GROUP_TYPE } from '@mui-builder/core';
-import { FIELD_TYPE } from 'packages/components/form/src/types/public.types';
+import { Link, Route, Routes } from 'react-router-dom';
+import { Builder, IFormTextBuilderProps } from '@mui-builder/core';
export function App() {
+ const groupList: IFormTextBuilderProps[] = [
+ {
+ id: '1',
+ groupType: 'form',
+ type: 'field-text',
+ props: {
+ id: 'type-1',
+ formId: '20',
+ },
+ },
+ {
+ id: '2',
+ groupType: 'form',
+ type: 'field-text',
+ props: {
+ id: 'type-2',
+ formId: '20',
+ helperText: 'mmd',
+ },
+ },
+ {
+ id: '3',
+ groupType: 'form',
+ type: 'field-text',
+ props: {
+ id: 'type-2',
+ formId: '21',
+ helperText: 'mmd',
+ },
+ },
+ {
+ id: '4',
+ groupType: 'form',
+ type: 'action-submit',
+ props: {
+ formId: '21',
+ children: 'submit 21',
+ },
+ },
+ {
+ id: '4',
+ groupType: 'form',
+ type: 'action-submit',
+ props: {
+ formId: '20',
+ children: 'submit 20',
+ },
+ },
+ ];
return (
-
-
-
-
@@ -33,55 +76,8 @@ export function App() {
}
/>
- {/*
} /> */}
-
- }
- />
-
- Click here to go back to root page.
-
- }
- />
+ } />
- {/* END: routes */}
);
}
diff --git a/package-lock.json b/package-lock.json
index 5a228e3..a7f5d23 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -15,6 +15,7 @@
"@changesets/cli": "^2.27.1",
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.0",
+ "@mui/lab": "^5.0.0-alpha.167",
"@mui/material": "^5.15.11",
"react": "18.2.0",
"react-dom": "18.2.0",
@@ -3870,6 +3871,77 @@
"url": "https://opencollective.com/mui-org"
}
},
+ "node_modules/@mui/lab": {
+ "version": "5.0.0-alpha.167",
+ "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-5.0.0-alpha.167.tgz",
+ "integrity": "sha512-BNQJ7fBBvL68WGVnzAhbtTmabSuJDXaILr9dz/3RNK4TgGXPgWCAr7qtJeUdc4p1t7c4Z1ifG8UwgqD+5hzMNg==",
+ "dependencies": {
+ "@babel/runtime": "^7.23.9",
+ "@mui/base": "5.0.0-beta.38",
+ "@mui/system": "^5.15.12",
+ "@mui/types": "^7.2.13",
+ "@mui/utils": "^5.15.12",
+ "clsx": "^2.1.0",
+ "prop-types": "^15.8.1"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/mui-org"
+ },
+ "peerDependencies": {
+ "@emotion/react": "^11.5.0",
+ "@emotion/styled": "^11.3.0",
+ "@mui/material": ">=5.15.0",
+ "@types/react": "^17.0.0 || ^18.0.0",
+ "react": "^17.0.0 || ^18.0.0",
+ "react-dom": "^17.0.0 || ^18.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@emotion/react": {
+ "optional": true
+ },
+ "@emotion/styled": {
+ "optional": true
+ },
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@mui/lab/node_modules/@mui/base": {
+ "version": "5.0.0-beta.38",
+ "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.38.tgz",
+ "integrity": "sha512-AsjD6Y1X5A1qndxz8xCcR8LDqv31aiwlgWMPxFAX/kCKiIGKlK65yMeVZ62iQr/6LBz+9hSKLiD1i4TZdAHKcQ==",
+ "dependencies": {
+ "@babel/runtime": "^7.23.9",
+ "@floating-ui/react-dom": "^2.0.8",
+ "@mui/types": "^7.2.13",
+ "@mui/utils": "^5.15.12",
+ "@popperjs/core": "^2.11.8",
+ "clsx": "^2.1.0",
+ "prop-types": "^15.8.1"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/mui-org"
+ },
+ "peerDependencies": {
+ "@types/react": "^17.0.0 || ^18.0.0",
+ "react": "^17.0.0 || ^18.0.0",
+ "react-dom": "^17.0.0 || ^18.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@mui/material": {
"version": "5.15.11",
"resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.11.tgz",
@@ -3915,12 +3987,12 @@
}
},
"node_modules/@mui/private-theming": {
- "version": "5.15.11",
- "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.11.tgz",
- "integrity": "sha512-jY/696SnSxSzO1u86Thym7ky5T9CgfidU3NFJjguldqK4f3Z5S97amZ6nffg8gTD0HBjY9scB+4ekqDEUmxZOA==",
+ "version": "5.15.12",
+ "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.12.tgz",
+ "integrity": "sha512-cqoSo9sgA5HE+8vZClbLrq9EkyOnYysooepi5eKaKvJ41lReT2c5wOZAeDDM1+xknrMDos+0mT2zr3sZmUiRRA==",
"dependencies": {
"@babel/runtime": "^7.23.9",
- "@mui/utils": "^5.15.11",
+ "@mui/utils": "^5.15.12",
"prop-types": "^15.8.1"
},
"engines": {
@@ -3972,15 +4044,15 @@
}
},
"node_modules/@mui/system": {
- "version": "5.15.11",
- "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.11.tgz",
- "integrity": "sha512-9j35suLFq+MgJo5ktVSHPbkjDLRMBCV17NMBdEQurh6oWyGnLM4uhU4QGZZQ75o0vuhjJghOCA1jkO3+79wKsA==",
+ "version": "5.15.12",
+ "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.12.tgz",
+ "integrity": "sha512-/pq+GO6yN3X7r3hAwFTrzkAh7K1bTF5r8IzS79B9eyKJg7v6B/t4/zZYMR6OT9qEPtwf6rYN2Utg1e6Z7F1OgQ==",
"dependencies": {
"@babel/runtime": "^7.23.9",
- "@mui/private-theming": "^5.15.11",
+ "@mui/private-theming": "^5.15.12",
"@mui/styled-engine": "^5.15.11",
"@mui/types": "^7.2.13",
- "@mui/utils": "^5.15.11",
+ "@mui/utils": "^5.15.12",
"clsx": "^2.1.0",
"csstype": "^3.1.3",
"prop-types": "^15.8.1"
@@ -4024,9 +4096,9 @@
}
},
"node_modules/@mui/utils": {
- "version": "5.15.11",
- "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.11.tgz",
- "integrity": "sha512-D6bwqprUa9Stf8ft0dcMqWyWDKEo7D+6pB1k8WajbqlYIRA8J8Kw9Ra7PSZKKePGBGWO+/xxrX1U8HpG/aXQCw==",
+ "version": "5.15.12",
+ "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.12.tgz",
+ "integrity": "sha512-8SDGCnO2DY9Yy+5bGzu00NZowSDtuyHP4H8gunhHGQoIlhlY2Z3w64wBzAOLpYw/ZhJNzksDTnS/i8qdJvxuow==",
"dependencies": {
"@babel/runtime": "^7.23.9",
"@types/prop-types": "^15.7.11",
diff --git a/package.json b/package.json
index a8e038c..fc37f11 100644
--- a/package.json
+++ b/package.json
@@ -10,6 +10,7 @@
"@changesets/cli": "^2.27.1",
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.0",
+ "@mui/lab": "^5.0.0-alpha.167",
"@mui/material": "^5.15.11",
"react": "18.2.0",
"react-dom": "18.2.0",
diff --git a/packages/components/form/src/components/actions/base/actionBase.tsx b/packages/components/form/src/components/actions/base/actionBase.tsx
new file mode 100644
index 0000000..f673024
--- /dev/null
+++ b/packages/components/form/src/components/actions/base/actionBase.tsx
@@ -0,0 +1,9 @@
+import { LoadingButton } from '@mui/lab';
+import { FC } from 'react';
+import { ActionBaseProps } from './actionBase.types';
+
+const ActionBase: FC = ({ children, ...actionBaseProps }) => {
+ return {children};
+};
+
+export default ActionBase;
diff --git a/packages/components/form/src/components/actions/base/actionBase.types.ts b/packages/components/form/src/components/actions/base/actionBase.types.ts
new file mode 100644
index 0000000..f4e026f
--- /dev/null
+++ b/packages/components/form/src/components/actions/base/actionBase.types.ts
@@ -0,0 +1,6 @@
+import { LoadingButtonProps } from '@mui/lab';
+import { ReactNode } from 'react';
+
+export type ActionBaseProps = LoadingButtonProps & {
+ children: ReactNode;
+};
diff --git a/packages/components/form/src/components/actions/submit/submit.tsx b/packages/components/form/src/components/actions/submit/submit.tsx
new file mode 100644
index 0000000..f442153
--- /dev/null
+++ b/packages/components/form/src/components/actions/submit/submit.tsx
@@ -0,0 +1,25 @@
+import { Button } from '@mui/material';
+import { FC } from 'react';
+import { ActionSubmitFieldProps } from './submit.types';
+import useForms from '../../../hooks/useForms/useForms';
+import { FieldValues } from 'react-hook-form';
+
+const ActionSubmit: FC = ({
+ formId,
+ children,
+ ...submitFieldProps
+}) => {
+ const forms = useForms((state) => state.forms);
+ const { handleSubmit } = forms[formId];
+ const onSubmit = (values: FieldValues) => {
+ console.log(values);
+ };
+
+ return (
+
+ );
+};
+
+export default ActionSubmit;
diff --git a/packages/components/form/src/components/actions/submit/submit.types.ts b/packages/components/form/src/components/actions/submit/submit.types.ts
new file mode 100644
index 0000000..7e4bf25
--- /dev/null
+++ b/packages/components/form/src/components/actions/submit/submit.types.ts
@@ -0,0 +1,4 @@
+import { FormId } from '../../../types/public.types';
+import { ActionBaseProps } from '../base/actionBase.types';
+
+export type ActionSubmitFieldProps = ActionBaseProps & FormId;
diff --git a/packages/components/form/src/components/builder/builder.types.ts b/packages/components/form/src/components/builder/builder.types.ts
index c6d719a..36f3b4c 100644
--- a/packages/components/form/src/components/builder/builder.types.ts
+++ b/packages/components/form/src/components/builder/builder.types.ts
@@ -1,6 +1,6 @@
-import { FIELD_TYPE, FieldProps } from '../../types/public.types';
+import { FormTypes, FieldProps } from '../../types/public.types';
export interface BuilderProps {
- fieldType: FIELD_TYPE;
+ fieldType: FormTypes;
fieldProps: FieldProps;
-}
\ No newline at end of file
+}
diff --git a/packages/components/form/src/components/text/text.tsx b/packages/components/form/src/components/fields/text/text.tsx
similarity index 90%
rename from packages/components/form/src/components/text/text.tsx
rename to packages/components/form/src/components/fields/text/text.tsx
index 7647fa5..6844f2b 100644
--- a/packages/components/form/src/components/text/text.tsx
+++ b/packages/components/form/src/components/fields/text/text.tsx
@@ -2,7 +2,7 @@ import { TextField } from '@mui/material';
import { FC } from 'react';
import { useController } from 'react-hook-form';
import { TextProps } from './text.types';
-import useForms from '../../hooks/useForms/useForms';
+import useForms from '../../../hooks/useForms/useForms';
const Text: FC = ({ formId, ...textFieldProps }) => {
const { forms } = useForms();
@@ -12,7 +12,7 @@ const Text: FC = ({ formId, ...textFieldProps }) => {
control: formMethod.control,
rules: { required: true },
});
-
+
return ;
};
diff --git a/packages/components/form/src/components/text/text.types.ts b/packages/components/form/src/components/fields/text/text.types.ts
similarity index 63%
rename from packages/components/form/src/components/text/text.types.ts
rename to packages/components/form/src/components/fields/text/text.types.ts
index 701a407..07fbb67 100644
--- a/packages/components/form/src/components/text/text.types.ts
+++ b/packages/components/form/src/components/fields/text/text.types.ts
@@ -1,4 +1,4 @@
import { TextFieldProps } from "@mui/material";
-import { FormId, Id } from "../../types/public.types";
+import { FormId, Id } from "../../../types/public.types";
export type TextProps = TextFieldProps & Id & FormId;
diff --git a/packages/components/form/src/types/public.types.ts b/packages/components/form/src/types/public.types.ts
index 1948b98..93453cd 100644
--- a/packages/components/form/src/types/public.types.ts
+++ b/packages/components/form/src/types/public.types.ts
@@ -1,4 +1,5 @@
-import { TextProps } from "../components/text/text.types";
+import { ActionSubmitFieldProps } from "../components/actions/submit/submit.types";
+import { TextProps } from "../components/fields/text/text.types";
export type FormId = { formId: string };
@@ -6,8 +7,6 @@ export type Id = {
id: string;
};
-export enum FIELD_TYPE {
- TEXT = 'text',
-}
+export type FormTypes = 'field-text' | "action-submit";
-export type FieldProps = TextProps;
+export type FieldProps = TextProps | ActionSubmitFieldProps;
diff --git a/packages/components/form/src/utils/selector/selector.tsx b/packages/components/form/src/utils/selector/selector.tsx
index adaa86c..d84c162 100644
--- a/packages/components/form/src/utils/selector/selector.tsx
+++ b/packages/components/form/src/utils/selector/selector.tsx
@@ -1,13 +1,16 @@
import { FC, Fragment, Suspense, lazy } from 'react';
-import { TextProps } from '../../components/text/text.types';
import { SelectorProps } from './selector.types';
+import { TextProps } from '../../components/fields/text/text.types';
+import { ActionSubmitFieldProps } from '../../components/actions/submit/submit.types';
const Selector: FC = ({ fieldType, fieldProps }) => {
let SelectedComponent;
switch (fieldType) {
- case 'text':
- SelectedComponent = lazy(() => import('../../components/text/text'));
+ case 'field-text':
+ SelectedComponent = lazy(
+ () => import('../../components/fields/text/text')
+ );
return (
Loading...}>
@@ -15,6 +18,17 @@ const Selector: FC = ({ fieldType, fieldProps }) => {
);
+ case 'action-submit':
+ SelectedComponent = lazy(
+ () => import('../../components/actions/submit/submit')
+ );
+
+ return (
+ Loading...}>
+
+
+ );
+
default:
SelectedComponent = Fragment;
diff --git a/packages/components/form/src/utils/selector/selector.types.ts b/packages/components/form/src/utils/selector/selector.types.ts
index fe9b2a8..a1b5e30 100644
--- a/packages/components/form/src/utils/selector/selector.types.ts
+++ b/packages/components/form/src/utils/selector/selector.types.ts
@@ -1,6 +1,6 @@
-import { FIELD_TYPE, FieldProps } from "../../types/public.types";
+import { FormTypes, FieldProps } from '../../types/public.types';
export interface SelectorProps {
- fieldType: FIELD_TYPE;
- fieldProps: FieldProps;
- }
\ No newline at end of file
+ fieldType: FormTypes;
+ fieldProps: FieldProps;
+}
diff --git a/packages/core/src/lib/components/builder/builder.tsx b/packages/core/src/lib/components/builder/builder.tsx
index 28d8769..1a0c9d5 100644
--- a/packages/core/src/lib/components/builder/builder.tsx
+++ b/packages/core/src/lib/components/builder/builder.tsx
@@ -1,14 +1,11 @@
import React from 'react';
import Selector from '../../utils/selector/selector';
import {
- FIELD_TYPE,
+ FormTypes,
FieldProps,
} from 'packages/components/form/src/types/public.types';
-export enum GROUP_TYPE {
- FORM = 'form',
- SECTION = 'section',
-}
+export type GROUP_TYPE = 'form';
export enum SECTION_TYPE {
CARD = 'card',
@@ -17,7 +14,7 @@ export enum SECTION_TYPE {
export interface IFormTextBuilderProps {
id: string;
groupType: GROUP_TYPE;
- type: FIELD_TYPE;
+ type: FormTypes;
props: FieldProps;
}
diff --git a/packages/core/src/lib/utils/selector/selector.tsx b/packages/core/src/lib/utils/selector/selector.tsx
index ede3e67..4ede482 100644
--- a/packages/core/src/lib/utils/selector/selector.tsx
+++ b/packages/core/src/lib/utils/selector/selector.tsx
@@ -1,21 +1,17 @@
import { FC, Fragment, Suspense, lazy } from 'react';
import { GROUP_TYPE } from '../../components/builder/builder';
import {
- FIELD_TYPE,
+ FormTypes,
FieldProps,
} from 'packages/components/form/src/types/public.types';
export interface SelectorProps {
groupType: GROUP_TYPE;
- fieldType: FIELD_TYPE;
+ fieldType: FormTypes;
fieldProps: FieldProps;
}
-const Selector: FC = ({
- groupType,
- fieldType,
- fieldProps,
-}) => {
+const Selector: FC = ({ groupType, fieldType, fieldProps }) => {
let SelectedComponent;
switch (groupType) {