dynamic-modal 1.1.4 → 1.1.7
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-ES.md +217 -217
- package/README.md +216 -216
- package/dist/components/input-upload/input-upload.js +1 -1
- package/dist/components/make-button/make-button.js +7 -17
- package/dist/components/make-input/make-input.js +7 -17
- package/dist/components/make-select/make-select.js +7 -17
- package/dist/components/make-textarea/make-textarea.js +7 -17
- package/dist/components/make-toggle/make-toggle.js +7 -17
- package/dist/components/portal/portal.js +7 -17
- package/dist/context/component/component-state.js +7 -17
- package/dist/interfaces/modal.d.ts +1 -0
- package/dist/modal.js +38 -19
- package/eslint.config.mjs +14 -14
- package/examples/enable-if.ts +127 -127
- package/examples/live-data.ts +61 -61
- package/examples/render-if.ts +128 -128
- package/examples/simple.ts +74 -74
- package/index.ts +5 -5
- package/package.json +46 -47
- package/src/components/input-upload/input-upload.tsx +67 -67
- package/src/components/make-button/make-button.tsx +18 -18
- package/src/components/make-description/make-description.tsx +15 -15
- package/src/components/make-input/make-input.tsx +53 -53
- package/src/components/make-select/make-select.tsx +55 -55
- package/src/components/make-textarea/make-textarea.tsx +53 -53
- package/src/components/make-toggle/make-toggle.tsx +53 -53
- package/src/components/make-upload/make-upload.tsx +40 -40
- package/src/components/portal/portal.tsx +37 -37
- package/src/context/component/component-state.tsx +17 -17
- package/src/hooks/field-render.ts +109 -109
- package/src/hooks/modal-handler.ts +38 -38
- package/src/interfaces/component-state.ts +33 -33
- package/src/interfaces/field.ts +37 -37
- package/src/interfaces/input-upload.ts +21 -21
- package/src/interfaces/make-button.ts +19 -19
- package/src/interfaces/make-description.ts +14 -14
- package/src/interfaces/make-field-group.ts +14 -14
- package/src/interfaces/make-input.ts +14 -14
- package/src/interfaces/make-select.ts +15 -15
- package/src/interfaces/make-textarea.ts +11 -11
- package/src/interfaces/make-toggle.ts +9 -9
- package/src/interfaces/make-upload.ts +14 -14
- package/src/interfaces/modal.ts +47 -46
- package/src/interfaces/option.ts +3 -3
- package/src/interfaces/portal.ts +8 -8
- package/src/modal.tsx +196 -164
- package/src/tools/general.ts +8 -8
- package/tsconfig.json +13 -13
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { IField, IFieldProps } from './field'
|
|
2
|
-
import { IModalLiveDataCondition } from './modal'
|
|
3
|
-
import { IOption } from './option'
|
|
4
|
-
|
|
5
|
-
export interface IMakeSelect extends IField {
|
|
6
|
-
elementType: 'select'
|
|
7
|
-
options: Array<IOption>
|
|
8
|
-
liveData?: IModalLiveDataCondition
|
|
9
|
-
isSearch?: boolean
|
|
10
|
-
isMulti?: boolean
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export interface IMakeSelectProps extends IFieldProps {
|
|
14
|
-
element: Omit<IMakeSelect, 'elementType'>
|
|
15
|
-
}
|
|
1
|
+
import { IField, IFieldProps } from './field'
|
|
2
|
+
import { IModalLiveDataCondition } from './modal'
|
|
3
|
+
import { IOption } from './option'
|
|
4
|
+
|
|
5
|
+
export interface IMakeSelect extends IField {
|
|
6
|
+
elementType: 'select'
|
|
7
|
+
options: Array<IOption>
|
|
8
|
+
liveData?: IModalLiveDataCondition
|
|
9
|
+
isSearch?: boolean
|
|
10
|
+
isMulti?: boolean
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface IMakeSelectProps extends IFieldProps {
|
|
14
|
+
element: Omit<IMakeSelect, 'elementType'>
|
|
15
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { IField, IFieldProps } from './field'
|
|
2
|
-
|
|
3
|
-
export interface IMakeTextarea extends IField {
|
|
4
|
-
elementType: 'textarea'
|
|
5
|
-
cols?: number
|
|
6
|
-
rows?: number
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export interface IMakeTextareaProps extends IFieldProps {
|
|
10
|
-
element: Omit<IMakeTextarea, 'elementType'>
|
|
11
|
-
}
|
|
1
|
+
import { IField, IFieldProps } from './field'
|
|
2
|
+
|
|
3
|
+
export interface IMakeTextarea extends IField {
|
|
4
|
+
elementType: 'textarea'
|
|
5
|
+
cols?: number
|
|
6
|
+
rows?: number
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface IMakeTextareaProps extends IFieldProps {
|
|
10
|
+
element: Omit<IMakeTextarea, 'elementType'>
|
|
11
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { IField, IFieldProps } from './field'
|
|
2
|
-
|
|
3
|
-
export interface IMakeToggle extends IField {
|
|
4
|
-
elementType: 'toggle'
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export interface IMakeToggleProps extends IFieldProps {
|
|
8
|
-
element: Omit<IMakeToggle, 'elementType'>
|
|
9
|
-
}
|
|
1
|
+
import { IField, IFieldProps } from './field'
|
|
2
|
+
|
|
3
|
+
export interface IMakeToggle extends IField {
|
|
4
|
+
elementType: 'toggle'
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export interface IMakeToggleProps extends IFieldProps {
|
|
8
|
+
element: Omit<IMakeToggle, 'elementType'>
|
|
9
|
+
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { IField, IFieldProps } from './field'
|
|
2
|
-
|
|
3
|
-
export interface IMakeUpload extends Omit<IField, 'defaultValue'> {
|
|
4
|
-
elementType: 'upload'
|
|
5
|
-
helpText?: string
|
|
6
|
-
read: boolean
|
|
7
|
-
image?: boolean
|
|
8
|
-
accept?:string
|
|
9
|
-
readAsArrayBuffer?: boolean
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export interface IMakeUploadProps extends IFieldProps {
|
|
13
|
-
element: Omit<IMakeUpload, 'elementType'>
|
|
14
|
-
}
|
|
1
|
+
import { IField, IFieldProps } from './field'
|
|
2
|
+
|
|
3
|
+
export interface IMakeUpload extends Omit<IField, 'defaultValue'> {
|
|
4
|
+
elementType: 'upload'
|
|
5
|
+
helpText?: string
|
|
6
|
+
read: boolean
|
|
7
|
+
image?: boolean
|
|
8
|
+
accept?:string
|
|
9
|
+
readAsArrayBuffer?: boolean
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface IMakeUploadProps extends IFieldProps {
|
|
13
|
+
element: Omit<IMakeUpload, 'elementType'>
|
|
14
|
+
}
|
package/src/interfaces/modal.ts
CHANGED
|
@@ -1,46 +1,47 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
import { CSSProperties } from 'react'
|
|
3
|
-
import { IMakeSelect } from './make-select'
|
|
4
|
-
import { IMakeInput } from './make-input'
|
|
5
|
-
import { IMakeTextarea } from './make-textarea'
|
|
6
|
-
import { IMakeToggle } from './make-toggle'
|
|
7
|
-
import { IMakeDescription } from './make-description'
|
|
8
|
-
import { IMakeFieldGroup } from './make-field-group'
|
|
9
|
-
import { IMakeUpload } from './make-upload'
|
|
10
|
-
import { IOption } from './option'
|
|
11
|
-
import { IMakeButton } from './make-button'
|
|
12
|
-
|
|
13
|
-
export type IModalField = IMakeSelect | IMakeInput | IMakeFieldGroup | IMakeTextarea | IMakeToggle | IMakeDescription | IMakeUpload | IMakeButton
|
|
14
|
-
|
|
15
|
-
export type IFormField = IMakeSelect | IMakeInput | IMakeTextarea | IMakeToggle
|
|
16
|
-
|
|
17
|
-
export type IModalRenderCondition = Record<string, Array<string | number | boolean> | undefined>
|
|
18
|
-
|
|
19
|
-
export type IModalLiveDataCondition = {
|
|
20
|
-
action: (data: string, ...args: any[]) => Promise<Array<IOption>>
|
|
21
|
-
condition: Array<string>
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export interface IModalConfigProps {
|
|
25
|
-
reservedData?: Record<string, any>
|
|
26
|
-
title: string
|
|
27
|
-
fields: Array<IModalField>
|
|
28
|
-
out: (data: any) => void
|
|
29
|
-
onClose?: () => void
|
|
30
|
-
style?: CSSProperties
|
|
31
|
-
overFlowBody?: string | number
|
|
32
|
-
minHeightBody?: string | number
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import { CSSProperties } from 'react'
|
|
3
|
+
import { IMakeSelect } from './make-select'
|
|
4
|
+
import { IMakeInput } from './make-input'
|
|
5
|
+
import { IMakeTextarea } from './make-textarea'
|
|
6
|
+
import { IMakeToggle } from './make-toggle'
|
|
7
|
+
import { IMakeDescription } from './make-description'
|
|
8
|
+
import { IMakeFieldGroup } from './make-field-group'
|
|
9
|
+
import { IMakeUpload } from './make-upload'
|
|
10
|
+
import { IOption } from './option'
|
|
11
|
+
import { IMakeButton } from './make-button'
|
|
12
|
+
|
|
13
|
+
export type IModalField = IMakeSelect | IMakeInput | IMakeFieldGroup | IMakeTextarea | IMakeToggle | IMakeDescription | IMakeUpload | IMakeButton
|
|
14
|
+
|
|
15
|
+
export type IFormField = IMakeSelect | IMakeInput | IMakeTextarea | IMakeToggle
|
|
16
|
+
|
|
17
|
+
export type IModalRenderCondition = Record<string, Array<string | number | boolean> | undefined>
|
|
18
|
+
|
|
19
|
+
export type IModalLiveDataCondition = {
|
|
20
|
+
action: (data: string, ...args: any[]) => Promise<Array<IOption>>
|
|
21
|
+
condition: Array<string>
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface IModalConfigProps {
|
|
25
|
+
reservedData?: Record<string, any>
|
|
26
|
+
title: string
|
|
27
|
+
fields: Array<IModalField>
|
|
28
|
+
out: (data: any) => void
|
|
29
|
+
onClose?: () => void
|
|
30
|
+
style?: CSSProperties
|
|
31
|
+
overFlowBody?: string | number
|
|
32
|
+
minHeightBody?: string | number
|
|
33
|
+
useSubmit?: boolean
|
|
34
|
+
actions: {
|
|
35
|
+
containerStyle?: CSSProperties
|
|
36
|
+
cancel?: Omit<IMakeButton, 'elementType'>
|
|
37
|
+
action: Omit<IMakeButton, 'elementType'>
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export type IModalConfigLoader<T = any, D = any> = (props: T, action: (modalResult: D) => void) => IModalConfigProps
|
|
42
|
+
|
|
43
|
+
export interface IModal {
|
|
44
|
+
open: boolean
|
|
45
|
+
close: () => void
|
|
46
|
+
config: IModalConfigProps
|
|
47
|
+
}
|
package/src/interfaces/option.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export interface IOption {
|
|
2
|
-
id: string
|
|
3
|
-
name: string
|
|
1
|
+
export interface IOption {
|
|
2
|
+
id: string
|
|
3
|
+
name: string
|
|
4
4
|
}
|
package/src/interfaces/portal.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { ReactNode } from 'react'
|
|
2
|
-
|
|
3
|
-
export interface IPortal {
|
|
4
|
-
children: ReactNode
|
|
5
|
-
closeTime: number
|
|
6
|
-
portalOpen: boolean
|
|
7
|
-
portalTag?: string
|
|
8
|
-
}
|
|
1
|
+
import { ReactNode } from 'react'
|
|
2
|
+
|
|
3
|
+
export interface IPortal {
|
|
4
|
+
children: ReactNode
|
|
5
|
+
closeTime: number
|
|
6
|
+
portalOpen: boolean
|
|
7
|
+
portalTag?: string
|
|
8
|
+
}
|
package/src/modal.tsx
CHANGED
|
@@ -1,164 +1,196 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
|
|
3
|
-
import React, { useContext, useEffect, useState } from 'react'
|
|
4
|
-
import { useForm } from 'react-hook-form'
|
|
5
|
-
import { Portal } from './components/portal/portal'
|
|
6
|
-
import MakeToggle from './components/make-toggle/make-toggle'
|
|
7
|
-
import MakeInput from './components/make-input/make-input'
|
|
8
|
-
import MakeSelect from './components/make-select/make-select'
|
|
9
|
-
import MakeTextarea from './components/make-textarea/make-textarea'
|
|
10
|
-
import { IModal, IModalField, IModalConfigProps, IFormField } from './interfaces/modal'
|
|
11
|
-
import MakeDescription from './components/make-description/make-description'
|
|
12
|
-
import { IFieldProps } from './interfaces/field'
|
|
13
|
-
import MakeUpload from './components/make-upload/make-upload'
|
|
14
|
-
import MakeButton from './components/make-button/make-button'
|
|
15
|
-
import { IMakeInput } from './interfaces/make-input'
|
|
16
|
-
import { IMakeSelect } from './interfaces/make-select'
|
|
17
|
-
import { IMakeTextarea } from './interfaces/make-textarea'
|
|
18
|
-
import { IMakeToggle } from './interfaces/make-toggle'
|
|
19
|
-
import { IMakeDescription } from './interfaces/make-description'
|
|
20
|
-
import { IMakeUpload } from './interfaces/make-upload'
|
|
21
|
-
import { IMakeButton } from './interfaces/make-button'
|
|
22
|
-
import { ComponentStateContext } from './context/component/component-state'
|
|
23
|
-
|
|
24
|
-
export const Modal = ({ open, close, config }: IModal) => {
|
|
25
|
-
const { ModalButtonAction, ModalButtonCancel } = useContext(ComponentStateContext)
|
|
26
|
-
const [modalReady, setModalReady] = useState<IModalConfigProps | undefined>(undefined)
|
|
27
|
-
const [defaultLoaded, setDefaultLoaded] = useState<boolean>(false)
|
|
28
|
-
|
|
29
|
-
const {
|
|
30
|
-
control,
|
|
31
|
-
handleSubmit,
|
|
32
|
-
getValues,
|
|
33
|
-
unregister,
|
|
34
|
-
setValue,
|
|
35
|
-
watch
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
{
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import React, { useContext, useEffect, useState } from 'react'
|
|
4
|
+
import { useForm } from 'react-hook-form'
|
|
5
|
+
import { Portal } from './components/portal/portal'
|
|
6
|
+
import MakeToggle from './components/make-toggle/make-toggle'
|
|
7
|
+
import MakeInput from './components/make-input/make-input'
|
|
8
|
+
import MakeSelect from './components/make-select/make-select'
|
|
9
|
+
import MakeTextarea from './components/make-textarea/make-textarea'
|
|
10
|
+
import { IModal, IModalField, IModalConfigProps, IFormField } from './interfaces/modal'
|
|
11
|
+
import MakeDescription from './components/make-description/make-description'
|
|
12
|
+
import { IFieldProps } from './interfaces/field'
|
|
13
|
+
import MakeUpload from './components/make-upload/make-upload'
|
|
14
|
+
import MakeButton from './components/make-button/make-button'
|
|
15
|
+
import { IMakeInput } from './interfaces/make-input'
|
|
16
|
+
import { IMakeSelect } from './interfaces/make-select'
|
|
17
|
+
import { IMakeTextarea } from './interfaces/make-textarea'
|
|
18
|
+
import { IMakeToggle } from './interfaces/make-toggle'
|
|
19
|
+
import { IMakeDescription } from './interfaces/make-description'
|
|
20
|
+
import { IMakeUpload } from './interfaces/make-upload'
|
|
21
|
+
import { IMakeButton } from './interfaces/make-button'
|
|
22
|
+
import { ComponentStateContext } from './context/component/component-state'
|
|
23
|
+
|
|
24
|
+
export const Modal = ({ open, close, config }: IModal) => {
|
|
25
|
+
const { ModalButtonAction, ModalButtonCancel } = useContext(ComponentStateContext)
|
|
26
|
+
const [modalReady, setModalReady] = useState<IModalConfigProps | undefined>(undefined)
|
|
27
|
+
const [defaultLoaded, setDefaultLoaded] = useState<boolean>(false)
|
|
28
|
+
|
|
29
|
+
const {
|
|
30
|
+
control,
|
|
31
|
+
handleSubmit,
|
|
32
|
+
getValues,
|
|
33
|
+
unregister,
|
|
34
|
+
setValue,
|
|
35
|
+
watch,
|
|
36
|
+
trigger,
|
|
37
|
+
getFieldState
|
|
38
|
+
} = useForm()
|
|
39
|
+
|
|
40
|
+
const formValueHandler = (element: IFormField) => {
|
|
41
|
+
if (['group', 'upload', 'text'].includes(element.elementType)) return
|
|
42
|
+
if(!element.defaultValue && element.renderIf) {
|
|
43
|
+
unregister(element.name)
|
|
44
|
+
return
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const defaultValue = element.defaultValue ?? ''
|
|
48
|
+
const parsedValue: boolean | string | Array<string> | undefined = defaultValue === 'true' ? true : defaultValue === 'false' ? false : defaultValue
|
|
49
|
+
setValue(element.name, parsedValue ?? '')
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const autoLoadGroup = (groupFields: Array<IModalField>) => {
|
|
53
|
+
groupFields.forEach(element => {
|
|
54
|
+
formValueHandler(element as IFormField)
|
|
55
|
+
})
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const autoLoadField = (modalFields: Array<IModalField>) => {
|
|
59
|
+
if (defaultLoaded) return
|
|
60
|
+
|
|
61
|
+
modalFields.forEach(element => {
|
|
62
|
+
if (element.elementType === 'group') {
|
|
63
|
+
autoLoadGroup(element.groups)
|
|
64
|
+
return
|
|
65
|
+
}
|
|
66
|
+
formValueHandler(element as IFormField)
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
setDefaultLoaded(true)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
const getUseSubmit = (modalConfig: IModalConfigProps): boolean => {
|
|
74
|
+
const useSubmit = modalConfig.useSubmit === undefined ? true : modalConfig.useSubmit === false ? false : true
|
|
75
|
+
|
|
76
|
+
return useSubmit
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const getRender = ({ elementType, ...element }: IModalField, index: number, isEndOfRender: boolean = false) => {
|
|
80
|
+
if (isEndOfRender && modalReady) setTimeout(() => autoLoadField(modalReady.fields), 200)
|
|
81
|
+
|
|
82
|
+
const props: IFieldProps = {
|
|
83
|
+
control,
|
|
84
|
+
watch,
|
|
85
|
+
setValue,
|
|
86
|
+
unregister
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return elementType === 'input'
|
|
90
|
+
? <MakeInput {...props} key={`modal-input-${index}`} element={element as IMakeInput} />
|
|
91
|
+
: elementType === 'select'
|
|
92
|
+
? <MakeSelect {...props} key={`modal-select-${index}`} element={element as IMakeSelect} />
|
|
93
|
+
: elementType === 'textarea'
|
|
94
|
+
? <MakeTextarea {...props} key={`modal-textarea-${index}`} element={element as IMakeTextarea} />
|
|
95
|
+
: elementType === 'toggle'
|
|
96
|
+
? <MakeToggle {...props} key={`modal-toggle-${index}`} element={element as IMakeToggle} />
|
|
97
|
+
: elementType === 'text'
|
|
98
|
+
? <MakeDescription {...props} key={`modal-text-${index}`} element={element as IMakeDescription} />
|
|
99
|
+
: elementType === 'upload'
|
|
100
|
+
? <MakeUpload {...props} key={`modal-upload-${index}`} element={element as IMakeUpload} />
|
|
101
|
+
: elementType === 'button'
|
|
102
|
+
? <MakeButton {...props} key={`modal-button-${index}`} element={element as IMakeButton} />
|
|
103
|
+
: null
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
const closeHandler = (): void => {
|
|
108
|
+
if (modalReady?.onClose) modalReady.onClose()
|
|
109
|
+
|
|
110
|
+
setTimeout(() => {
|
|
111
|
+
const form = getValues()
|
|
112
|
+
unregister(Object.keys(form))
|
|
113
|
+
setModalReady(undefined)
|
|
114
|
+
setDefaultLoaded(false)
|
|
115
|
+
close()
|
|
116
|
+
}, 200)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const manualSubmit = async (): Promise<void> => {
|
|
120
|
+
const form = getValues()
|
|
121
|
+
const fields = Object.keys(form)
|
|
122
|
+
await trigger(fields)
|
|
123
|
+
|
|
124
|
+
const validations: Array<boolean> = fields.map(field => {
|
|
125
|
+
const { invalid } = getFieldState(field)
|
|
126
|
+
|
|
127
|
+
return invalid
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
const result = validations.some(isInvalid => isInvalid) ? undefined : form
|
|
131
|
+
|
|
132
|
+
if(!result) return
|
|
133
|
+
|
|
134
|
+
actionHandler({ ...(modalReady?.reservedData ?? {}), ...form })
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const actionHandler = (data: Record<string, string | number | object>): void => {
|
|
138
|
+
modalReady?.out({ ...(modalReady?.reservedData ?? {}), ...data })
|
|
139
|
+
closeHandler()
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
useEffect(() => {
|
|
143
|
+
if (open && !modalReady) setModalReady(config)
|
|
144
|
+
}, [config, modalReady, open])
|
|
145
|
+
|
|
146
|
+
return (
|
|
147
|
+
modalReady
|
|
148
|
+
? <Portal closeTime={200} portalOpen={open} portalTag={'#modal-portal'}>
|
|
149
|
+
<div className='rounded bg-white relative w-auto h-auto min-h-[200px] min-w-[500px]' style={modalReady.style} >
|
|
150
|
+
<form className='flex flex-col p-4 gap-4' autoComplete='off' onSubmit={handleSubmit(actionHandler)}>
|
|
151
|
+
<h2 className='text-bold text-center border-b pb-4 font-semibold'>{modalReady.title}</h2>
|
|
152
|
+
<div
|
|
153
|
+
className='flex flex-col gap-4 py-4'
|
|
154
|
+
style={{
|
|
155
|
+
overflowY: modalReady.overFlowBody ? 'auto' : undefined,
|
|
156
|
+
height: modalReady.overFlowBody,
|
|
157
|
+
minHeight: modalReady.minHeightBody
|
|
158
|
+
}}
|
|
159
|
+
>
|
|
160
|
+
{
|
|
161
|
+
modalReady.fields.map((element, index) => {
|
|
162
|
+
const isEndOfRender: boolean = index + 1 === modalReady.fields.length
|
|
163
|
+
|
|
164
|
+
if (element.elementType === 'group') {
|
|
165
|
+
return (
|
|
166
|
+
<div key={`modal-group-${index}`} className='flex flex-col w-full gap-2'>
|
|
167
|
+
{ element.title && <h3 className='font-bold border-b-2 pb-2 mb-2'>{element.title}</h3> }
|
|
168
|
+
<div key={`modal-group-${index}`} className='flex gap-4 w-full' style={element.style}>
|
|
169
|
+
{
|
|
170
|
+
element.groups
|
|
171
|
+
.filter(sub => ['input', 'select', 'toggle', 'multiselect', 'upload', 'button', 'autocomplete'].includes(sub.elementType))
|
|
172
|
+
.map((sub, subIndex) => getRender(sub, index + subIndex, isEndOfRender))
|
|
173
|
+
}
|
|
174
|
+
</div>
|
|
175
|
+
</div>
|
|
176
|
+
)
|
|
177
|
+
} else { return getRender(element, index, isEndOfRender) }
|
|
178
|
+
})
|
|
179
|
+
}
|
|
180
|
+
</div>
|
|
181
|
+
<div className='flex gap-4 items-center justify-center border-t' style={modalReady?.actions.containerStyle}>
|
|
182
|
+
{modalReady.actions.cancel && <ModalButtonCancel {...modalReady.actions.cancel} onClick={closeHandler} />}
|
|
183
|
+
{
|
|
184
|
+
getUseSubmit(modalReady) ?
|
|
185
|
+
<ModalButtonAction {...modalReady.actions.action} type='submit' />:
|
|
186
|
+
<ModalButtonAction {...modalReady.actions.action} onClick={manualSubmit} type='button' />
|
|
187
|
+
}
|
|
188
|
+
</div>
|
|
189
|
+
</form>
|
|
190
|
+
</div>
|
|
191
|
+
</Portal>
|
|
192
|
+
: null
|
|
193
|
+
)
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export default Modal
|
package/src/tools/general.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
|
|
3
|
-
export const generateId = (): string => {
|
|
4
|
-
return Math.random()
|
|
5
|
-
.toString(36)
|
|
6
|
-
.split('.')[1]
|
|
7
|
-
.substring(0, 6)
|
|
8
|
-
}
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
export const generateId = (): string => {
|
|
4
|
+
return Math.random()
|
|
5
|
+
.toString(36)
|
|
6
|
+
.split('.')[1]
|
|
7
|
+
.substring(0, 6)
|
|
8
|
+
}
|
package/tsconfig.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2016",
|
|
4
|
-
"module": "commonjs",
|
|
5
|
-
"declaration": true,
|
|
6
|
-
"outDir": "./dist",
|
|
7
|
-
"strict": true,
|
|
8
|
-
"jsx": "react",
|
|
9
|
-
"esModuleInterop": true,
|
|
10
|
-
"skipLibCheck": true
|
|
11
|
-
},
|
|
12
|
-
"include": ["src/**/*"]
|
|
13
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2016",
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"declaration": true,
|
|
6
|
+
"outDir": "./dist",
|
|
7
|
+
"strict": true,
|
|
8
|
+
"jsx": "react",
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"skipLibCheck": true
|
|
11
|
+
},
|
|
12
|
+
"include": ["src/**/*"]
|
|
13
|
+
}
|