dynamic-modal 1.0.13 → 1.1.4
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 +109 -11
- package/README.md +111 -13
- package/dist/components/input-upload/input-upload.js +8 -42
- package/dist/components/make-button/make-button.js +41 -18
- package/dist/components/make-description/make-description.d.ts +4 -0
- package/dist/components/make-description/make-description.js +13 -0
- package/dist/components/make-input/make-input.d.ts +1 -1
- package/dist/components/make-input/make-input.js +14 -8
- package/dist/components/make-select/make-select.js +14 -8
- package/dist/components/make-textarea/make-textarea.js +14 -8
- package/dist/components/make-toggle/make-toggle.js +14 -11
- package/dist/components/make-upload/make-upload.js +10 -9
- package/dist/context/component/component-state.d.ts +4 -0
- package/dist/context/component/component-state.js +45 -0
- package/dist/hooks/field-render.js +1 -1
- package/dist/interfaces/component-state.d.ts +27 -0
- package/dist/interfaces/field.d.ts +6 -4
- package/dist/interfaces/input-upload.d.ts +1 -1
- package/dist/interfaces/make-button.d.ts +5 -6
- package/dist/interfaces/make-description.d.ts +12 -0
- package/dist/interfaces/make-field-group.d.ts +1 -0
- package/dist/interfaces/{make-field.d.ts → make-input.d.ts} +2 -2
- package/dist/interfaces/make-select.d.ts +5 -2
- package/dist/interfaces/make-textarea.d.ts +1 -1
- package/dist/interfaces/make-toggle.d.ts +1 -1
- package/dist/interfaces/make-upload.d.ts +1 -1
- package/dist/interfaces/modal.d.ts +15 -20
- package/dist/modal.js +42 -35
- package/dist/tools/general.js +1 -0
- package/examples/enable-if.ts +5 -7
- package/examples/live-data.ts +7 -9
- package/examples/render-if.ts +6 -8
- package/examples/simple.ts +6 -8
- package/index.ts +4 -2
- package/package.json +15 -16
- package/src/components/input-upload/input-upload.tsx +7 -12
- package/src/components/make-button/make-button.tsx +11 -10
- package/src/components/make-description/make-description.tsx +15 -0
- package/src/components/make-input/make-input.tsx +27 -21
- package/src/components/make-select/make-select.tsx +25 -24
- package/src/components/make-textarea/make-textarea.tsx +21 -16
- package/src/components/make-toggle/make-toggle.tsx +26 -17
- package/src/components/make-upload/make-upload.tsx +14 -8
- package/src/components/portal/portal.tsx +1 -0
- package/src/context/component/component-state.tsx +18 -0
- package/src/hooks/field-render.ts +6 -5
- package/src/hooks/modal-handler.ts +1 -0
- package/src/interfaces/component-state.ts +33 -0
- package/src/interfaces/field.ts +11 -9
- package/src/interfaces/input-upload.ts +11 -11
- package/src/interfaces/make-button.ts +10 -11
- package/src/interfaces/make-description.ts +14 -0
- package/src/interfaces/make-field-group.ts +5 -4
- package/src/interfaces/{make-field.ts → make-input.ts} +2 -2
- package/src/interfaces/make-select.ts +5 -2
- package/src/interfaces/make-textarea.ts +1 -1
- package/src/interfaces/make-toggle.ts +2 -2
- package/src/interfaces/make-upload.ts +7 -7
- package/src/interfaces/modal.ts +16 -21
- package/src/interfaces/option.ts +2 -2
- package/src/interfaces/portal.ts +4 -4
- package/src/modal.tsx +43 -53
- package/src/tools/general.ts +2 -0
- package/.idea/dynamic-modal.iml +0 -12
- package/.idea/inspectionProfiles/Project_Default.xml +0 -6
- package/.idea/modules.xml +0 -8
- package/.idea/vcs.xml +0 -6
- package/dist/components/make-autocomplete/make-autocomplete.d.ts +0 -4
- package/dist/components/make-autocomplete/make-autocomplete.js +0 -70
- package/dist/components/make-multi-select/make-multi-select.d.ts +0 -4
- package/dist/components/make-multi-select/make-multi-select.js +0 -70
- package/dist/components/make-text/make-text.d.ts +0 -4
- package/dist/components/make-text/make-text.js +0 -11
- package/dist/components/make-title/make-title.d.ts +0 -4
- package/dist/components/make-title/make-title.js +0 -10
- package/dist/interfaces/make-autocomplete.d.ts +0 -11
- package/dist/interfaces/make-multi-select.d.ts +0 -12
- package/dist/interfaces/make-text.d.ts +0 -10
- package/dist/interfaces/make-text.js +0 -2
- package/dist/interfaces/make-title.d.ts +0 -3
- package/dist/interfaces/make-title.js +0 -2
- package/src/components/make-autocomplete/make-autocomplete.tsx +0 -54
- package/src/components/make-multi-select/make-multi-select.tsx +0 -56
- package/src/components/make-text/make-text.tsx +0 -16
- package/src/components/make-title/make-title.tsx +0 -12
- package/src/interfaces/make-autocomplete.ts +0 -13
- package/src/interfaces/make-multi-select.ts +0 -14
- package/src/interfaces/make-text.ts +0 -12
- package/src/interfaces/make-title.ts +0 -3
- /package/dist/interfaces/{make-autocomplete.js → component-state.js} +0 -0
- /package/dist/interfaces/{make-field.js → make-description.js} +0 -0
- /package/dist/interfaces/{make-multi-select.js → make-input.js} +0 -0
package/index.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
'use client'
|
|
2
|
+
export { default as DynamicModal } from './src/modal'
|
|
2
3
|
export type { IModalConfigLoader, IModalConfigProps, IModalRenderCondition, IModalField, IModalLiveDataCondition } from './src/interfaces/modal'
|
|
3
|
-
export { useModalHandler } from './src/hooks/modal-handler'
|
|
4
|
+
export { useModalHandler } from './src/hooks/modal-handler'
|
|
5
|
+
export { ComponentState, ComponentStateContext } from './src/context/component/component-state';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dynamic-modal",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.4",
|
|
4
4
|
"description": "The dynamic-modal is a solution of creation different modals into project using a json configuration file",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -27,22 +27,21 @@
|
|
|
27
27
|
},
|
|
28
28
|
"homepage": "https://gitlab.com/f.salazar/dynamic-modal#readme",
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@eslint/js": "^9.
|
|
31
|
-
"@types/react": "^
|
|
32
|
-
"@types/react-dom": "^
|
|
33
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
34
|
-
"@typescript-eslint/parser": "^8.
|
|
35
|
-
"eslint": "^9.
|
|
36
|
-
"eslint-plugin-react": "^7.37.
|
|
37
|
-
"eslint-plugin-react-hooks": "^5.
|
|
38
|
-
"globals": "^
|
|
39
|
-
"typescript": "^5.
|
|
40
|
-
"typescript-eslint": "^8.
|
|
30
|
+
"@eslint/js": "^9.22.0",
|
|
31
|
+
"@types/react": "^19.0.10",
|
|
32
|
+
"@types/react-dom": "^19.0.4",
|
|
33
|
+
"@typescript-eslint/eslint-plugin": "^8.26.1",
|
|
34
|
+
"@typescript-eslint/parser": "^8.26.1",
|
|
35
|
+
"eslint": "^9.22.0",
|
|
36
|
+
"eslint-plugin-react": "^7.37.4",
|
|
37
|
+
"eslint-plugin-react-hooks": "^5.2.0",
|
|
38
|
+
"globals": "^16.0.0",
|
|
39
|
+
"typescript": "^5.8.2",
|
|
40
|
+
"typescript-eslint": "^8.26.1"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"
|
|
44
|
-
"react": "^
|
|
45
|
-
"react-
|
|
46
|
-
"react-hook-form": "^7.0.0"
|
|
43
|
+
"react": "^19.0.0",
|
|
44
|
+
"react-dom": "^19.0.0",
|
|
45
|
+
"react-hook-form": "^7.54.2"
|
|
47
46
|
}
|
|
48
47
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import React, { ChangeEvent, FC } from 'react'
|
|
2
4
|
import { IFileResult, IInputUpload } from '../../interfaces/input-upload'
|
|
3
|
-
import { generateId } from '../../tools/general'
|
|
4
5
|
|
|
5
6
|
const InputUpload: FC<IInputUpload> = ({ onChange, readAsArrayBuffer, ...props }: IInputUpload) => {
|
|
6
7
|
|
|
@@ -39,30 +40,24 @@ const InputUpload: FC<IInputUpload> = ({ onChange, readAsArrayBuffer, ...props }
|
|
|
39
40
|
})
|
|
40
41
|
}
|
|
41
42
|
|
|
42
|
-
const elementId = useMemo<string>(
|
|
43
|
-
() => {
|
|
44
|
-
return props.id ?? generateId()
|
|
45
|
-
}, [props.id]
|
|
46
|
-
)
|
|
47
|
-
|
|
48
43
|
return (
|
|
49
44
|
<div className='flex flex-col w-full gap-1 text-center'>
|
|
50
|
-
{props.label && <label className="block mb-2 text-sm font-medium text-gray-900 dark:text-white" htmlFor={`file-input-${
|
|
45
|
+
{props.label && <label className="block mb-2 text-sm font-medium text-gray-900 dark:text-white" htmlFor={`file-input-${props.id}`}>{props.label}</label>}
|
|
51
46
|
<input
|
|
52
47
|
className="file:transition-all file:delay-150 block w-full text-sm text-slate-500
|
|
53
48
|
file:mr-4 file:py-2 file:px-4 file:rounded-md
|
|
54
49
|
file:border-0 file:text-sm file:font-semibold
|
|
55
50
|
file:bg-gray-100 file:text-blue-600
|
|
56
51
|
hover:file:bg-blue-700 hover:file:text-white cursor-pointer disabled:cursor-not-allowed"
|
|
57
|
-
aria-describedby={`file-input-${
|
|
58
|
-
id={`file-input-${
|
|
52
|
+
aria-describedby={`file-input-${props.id}-help`}
|
|
53
|
+
id={`file-input-${props.id}`}
|
|
59
54
|
type="file"
|
|
60
55
|
onChange={onChangeHandler}
|
|
61
56
|
{...props}
|
|
62
57
|
/>
|
|
63
58
|
<p
|
|
64
59
|
className="mt-1 text-sm text-gray-500 dark:text-gray-300 text-start"
|
|
65
|
-
id={`file-input-${
|
|
60
|
+
id={`file-input-${props.id}-help`}>
|
|
66
61
|
{props.helpText?.toUpperCase()}
|
|
67
62
|
</p>
|
|
68
63
|
</div>
|
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import React, { FC, useContext, useMemo } from 'react'
|
|
2
4
|
import { IMakeButtonProps } from '../../interfaces/make-button'
|
|
5
|
+
import { ComponentStateContext } from '../../context/component/component-state'
|
|
6
|
+
import { generateId } from '../../tools/general'
|
|
7
|
+
|
|
8
|
+
const MakeButton: FC<IMakeButtonProps> = ({ element }) => {
|
|
9
|
+
const { Button } = useContext(ComponentStateContext)
|
|
3
10
|
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
}) => {
|
|
11
|
+
const elementId = useMemo(() => element.id ?? generateId(), [])
|
|
12
|
+
|
|
7
13
|
return (
|
|
8
|
-
<
|
|
9
|
-
className='transition-all delay-100 hover:translate-y-1 bg-blue-500 text-white hover:bg-blue-700 rounded w-11/12 h-[40px] p-2'
|
|
10
|
-
{...element}
|
|
11
|
-
>
|
|
12
|
-
{text}
|
|
13
|
-
</button>
|
|
14
|
+
<Button {...element} id={elementId} />
|
|
14
15
|
)
|
|
15
16
|
}
|
|
16
17
|
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import React, { FC } from 'react'
|
|
4
|
+
import { IMakeDescriptionProps } from '../../interfaces/make-description'
|
|
5
|
+
|
|
6
|
+
const MakeDescription: FC<IMakeDescriptionProps> = ({ element: { text, Icon, containerStyle, textStyle } }) => {
|
|
7
|
+
return (
|
|
8
|
+
<div className='flex gap-4 w-full h-auto text-xs text-center p-2 border-1 rounded-md' style={containerStyle}>
|
|
9
|
+
{Icon && <Icon />}
|
|
10
|
+
<p style={textStyle}>{text}</p>
|
|
11
|
+
</div>
|
|
12
|
+
)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export default MakeDescription
|
|
@@ -1,13 +1,18 @@
|
|
|
1
|
-
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import React, { FC, useContext, useEffect, useMemo } from 'react'
|
|
2
4
|
import { Controller } from 'react-hook-form'
|
|
3
5
|
import { useFieldRender } from '../../hooks/field-render'
|
|
4
|
-
import { IMakeInputProps } from '../../interfaces/make-
|
|
5
|
-
import {
|
|
6
|
+
import { IMakeInputProps } from '../../interfaces/make-input'
|
|
7
|
+
import { ComponentStateContext } from '../../context/component/component-state'
|
|
6
8
|
import { generateId } from '../../tools/general'
|
|
7
9
|
|
|
8
|
-
const MakeInput: FC<IMakeInputProps> = ({ element: { validation: { required, ...validation }, ...element }, ...props }) => {
|
|
9
|
-
const {
|
|
10
|
+
const MakeInput: FC<IMakeInputProps> = ({ element: { validation: { required, ...validation }, enableIf, renderIf, ...element }, ...props }) => {
|
|
11
|
+
const { Input } = useContext(ComponentStateContext)
|
|
12
|
+
const { render, enable, checkField } = useFieldRender({ ...props, element: { enableIf, renderIf, ...element} })
|
|
10
13
|
|
|
14
|
+
const elementId = useMemo(() => element.id ?? generateId(), [])
|
|
15
|
+
|
|
11
16
|
useEffect(() => {
|
|
12
17
|
const subscription = props.watch((value, { name, type }) => checkField(value, { name, type }))
|
|
13
18
|
return () => subscription.unsubscribe()
|
|
@@ -19,25 +24,26 @@ const MakeInput: FC<IMakeInputProps> = ({ element: { validation: { required, ...
|
|
|
19
24
|
control={props.control}
|
|
20
25
|
name={element.name}
|
|
21
26
|
rules={{
|
|
22
|
-
required
|
|
23
|
-
|
|
24
|
-
value: validation.regex as RegExp ?? /(.*)/,
|
|
27
|
+
required: {
|
|
28
|
+
value: required,
|
|
25
29
|
message: validation.message ?? ''
|
|
26
30
|
},
|
|
27
|
-
|
|
31
|
+
pattern: validation.regex ? {
|
|
32
|
+
value: validation.regex,
|
|
33
|
+
message: validation.message ?? ''
|
|
34
|
+
} : undefined,
|
|
35
|
+
...validation
|
|
28
36
|
}}
|
|
29
|
-
render={({ field: { onChange, value }, fieldState: { invalid } }) => (
|
|
30
|
-
<Input
|
|
31
|
-
|
|
32
|
-
{
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
isDisabled={element.disabled ?? !enable}
|
|
40
|
-
/>
|
|
37
|
+
render={({ field: { onChange, value }, fieldState: { invalid, error } }) => (
|
|
38
|
+
<Input
|
|
39
|
+
{...element}
|
|
40
|
+
id={elementId}
|
|
41
|
+
onChange={onChange}
|
|
42
|
+
value={value ?? ''}
|
|
43
|
+
invalid={invalid}
|
|
44
|
+
error={error}
|
|
45
|
+
disabled={element.disabled ?? !enable}
|
|
46
|
+
/>
|
|
41
47
|
)}
|
|
42
48
|
/>
|
|
43
49
|
: null
|
|
@@ -1,12 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import React, { FC, useContext, useEffect, useMemo } from 'react'
|
|
2
4
|
import { Controller } from 'react-hook-form'
|
|
3
5
|
import { useFieldRender } from '../../hooks/field-render'
|
|
4
6
|
import { generateId } from '../../tools/general'
|
|
5
7
|
import { IMakeSelectProps } from '../../interfaces/make-select'
|
|
6
|
-
import {
|
|
8
|
+
import { ComponentStateContext } from '../../context/component/component-state'
|
|
9
|
+
|
|
10
|
+
const MakeSelect: FC<IMakeSelectProps> = ({ element: { validation: { required, ...validation }, enableIf, renderIf, ...element }, ...props }) => {
|
|
11
|
+
const { Select } = useContext(ComponentStateContext)
|
|
12
|
+
const { render, enable, checkField, liveData, liveSearching } = useFieldRender({ ...props, element: { renderIf, enableIf, ...element} })
|
|
7
13
|
|
|
8
|
-
const
|
|
9
|
-
const { render, enable, checkField, liveData, liveSearching } = useFieldRender({ ...props, element })
|
|
14
|
+
const elementId = useMemo(() => element.id ?? generateId(), [])
|
|
10
15
|
|
|
11
16
|
useEffect(() => {
|
|
12
17
|
const subscription = props.watch((value, { name, type }) => checkField(value, { name, type }))
|
|
@@ -19,32 +24,28 @@ const MakeSelect: FC<IMakeSelectProps> = ({ element: { validation: { required, .
|
|
|
19
24
|
control={props.control}
|
|
20
25
|
name={element.name}
|
|
21
26
|
rules={{
|
|
22
|
-
required
|
|
23
|
-
|
|
24
|
-
value: validation.regex as RegExp ?? /(.*)/,
|
|
27
|
+
required: {
|
|
28
|
+
value: required,
|
|
25
29
|
message: validation.message ?? ''
|
|
26
30
|
},
|
|
27
|
-
|
|
31
|
+
pattern: validation.regex ? {
|
|
32
|
+
value: validation.regex,
|
|
33
|
+
message: validation.message ?? ''
|
|
34
|
+
} : undefined,
|
|
35
|
+
...validation
|
|
28
36
|
}}
|
|
29
|
-
render={({ field: { onChange, value }, fieldState: { invalid } }) => (
|
|
37
|
+
render={({ field: { onChange, value }, fieldState: { invalid, error } }) => (
|
|
30
38
|
<Select
|
|
31
|
-
size='sm'
|
|
32
39
|
{...element}
|
|
33
|
-
id={
|
|
40
|
+
id={elementId}
|
|
34
41
|
onChange={onChange}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
{
|
|
43
|
-
(liveData || (element.options ?? [])).map((opt) => (
|
|
44
|
-
<SelectItem key={opt.id} value={opt.id}>{opt.name}</SelectItem>
|
|
45
|
-
))
|
|
46
|
-
}
|
|
47
|
-
</Select>
|
|
42
|
+
value={value}
|
|
43
|
+
invalid={invalid}
|
|
44
|
+
error={error}
|
|
45
|
+
disabled={element.disabled ?? !enable}
|
|
46
|
+
liveSearching={liveSearching}
|
|
47
|
+
options={liveData || (element.options ?? [])}
|
|
48
|
+
/>
|
|
48
49
|
)}
|
|
49
50
|
/>
|
|
50
51
|
: <></>
|
|
@@ -1,13 +1,18 @@
|
|
|
1
|
-
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import React, { FC, useContext, useEffect, useMemo } from 'react'
|
|
2
4
|
import { Controller } from 'react-hook-form'
|
|
3
5
|
import { useFieldRender } from '../../hooks/field-render'
|
|
4
6
|
import { generateId } from '../../tools/general'
|
|
5
7
|
import { IMakeTextareaProps } from '../../interfaces/make-textarea'
|
|
6
|
-
import {
|
|
8
|
+
import { ComponentStateContext } from '../../context/component/component-state'
|
|
7
9
|
|
|
8
|
-
const MakeTextarea: FC<IMakeTextareaProps> = ({ element: { validation: { required, ...validation }, ...element }, ...props }) => {
|
|
9
|
-
const {
|
|
10
|
+
const MakeTextarea: FC<IMakeTextareaProps> = ({ element: { validation: { required, ...validation }, enableIf, renderIf, ...element }, ...props }) => {
|
|
11
|
+
const { Textarea } = useContext(ComponentStateContext)
|
|
12
|
+
const { render, enable, checkField } = useFieldRender({ ...props, element: { enableIf, renderIf, ...element } })
|
|
10
13
|
|
|
14
|
+
const elementId = useMemo(() => element.id ?? generateId(), [])
|
|
15
|
+
|
|
11
16
|
useEffect(() => {
|
|
12
17
|
const subscription = props.watch((value, { name, type }) => checkField(value, { name, type }))
|
|
13
18
|
return () => subscription.unsubscribe()
|
|
@@ -19,25 +24,25 @@ const MakeTextarea: FC<IMakeTextareaProps> = ({ element: { validation: { require
|
|
|
19
24
|
name={element.name}
|
|
20
25
|
control={props.control}
|
|
21
26
|
rules={{
|
|
22
|
-
required
|
|
23
|
-
|
|
24
|
-
value: validation.regex as RegExp ?? /(.*)/,
|
|
27
|
+
required: {
|
|
28
|
+
value: required,
|
|
25
29
|
message: validation.message ?? ''
|
|
26
30
|
},
|
|
27
|
-
|
|
31
|
+
pattern: validation.regex ? {
|
|
32
|
+
value: validation.regex,
|
|
33
|
+
message: validation.message ?? ''
|
|
34
|
+
} : undefined,
|
|
35
|
+
...validation
|
|
28
36
|
}}
|
|
29
|
-
render={({ field: { onChange, value }, fieldState: { invalid } }) => (
|
|
37
|
+
render={({ field: { onChange, value }, fieldState: { invalid, error } }) => (
|
|
30
38
|
<Textarea
|
|
31
39
|
{...element}
|
|
32
|
-
|
|
33
|
-
id={element.id ?? generateId()}
|
|
40
|
+
id={elementId}
|
|
34
41
|
onChange={onChange}
|
|
35
|
-
label={element.label}
|
|
36
42
|
value={value ?? ''}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
isDisabled={element.disabled ?? !enable}
|
|
43
|
+
invalid={invalid}
|
|
44
|
+
error={error}
|
|
45
|
+
disabled={element.disabled ?? !enable}
|
|
41
46
|
/>
|
|
42
47
|
)}
|
|
43
48
|
/>
|
|
@@ -1,13 +1,18 @@
|
|
|
1
|
-
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import React, { FC, useContext, useEffect, useMemo } from 'react'
|
|
2
4
|
import { Controller } from 'react-hook-form'
|
|
3
5
|
import { useFieldRender } from '../../hooks/field-render'
|
|
4
6
|
import { IMakeToggleProps } from '../../interfaces/make-toggle'
|
|
5
|
-
import { Switch } from '@nextui-org/react'
|
|
6
7
|
import { generateId } from '../../tools/general'
|
|
8
|
+
import { ComponentStateContext } from '../../context/component/component-state'
|
|
7
9
|
|
|
8
|
-
const MakeToggle: FC<IMakeToggleProps> = ({ element: { validation: { required, ...validation }, ...element }, ...props }) => {
|
|
9
|
-
const {
|
|
10
|
+
const MakeToggle: FC<IMakeToggleProps> = ({ element: { validation: { required, ...validation }, enableIf, renderIf, ...element }, ...props }) => {
|
|
11
|
+
const { Toggle } = useContext(ComponentStateContext)
|
|
12
|
+
const { render, enable, checkField } = useFieldRender({ ...props, element: { enableIf, renderIf, ...element } })
|
|
10
13
|
|
|
14
|
+
const elementId = useMemo(() => element.id ?? generateId(), [])
|
|
15
|
+
|
|
11
16
|
useEffect(() => {
|
|
12
17
|
const subscription = props.watch((value, { name, type }) => checkField(value, { name, type }))
|
|
13
18
|
return () => subscription.unsubscribe()
|
|
@@ -19,22 +24,26 @@ const MakeToggle: FC<IMakeToggleProps> = ({ element: { validation: { required, .
|
|
|
19
24
|
control={props.control}
|
|
20
25
|
name={element.name}
|
|
21
26
|
rules={{
|
|
22
|
-
required
|
|
23
|
-
|
|
24
|
-
|
|
27
|
+
required: {
|
|
28
|
+
value: required,
|
|
29
|
+
message: validation.message ?? ''
|
|
30
|
+
},
|
|
31
|
+
pattern: validation.regex ? {
|
|
32
|
+
value: validation.regex,
|
|
25
33
|
message: validation.message ?? ''
|
|
26
|
-
}
|
|
34
|
+
} : undefined,
|
|
35
|
+
...validation
|
|
27
36
|
}}
|
|
28
|
-
render={({ field: { onChange, value } }) => (
|
|
29
|
-
<
|
|
37
|
+
render={({ field: { onChange, value }, fieldState: { invalid, error } }) => (
|
|
38
|
+
<Toggle
|
|
30
39
|
{...element}
|
|
31
|
-
id={
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
{element.
|
|
37
|
-
|
|
40
|
+
id={elementId}
|
|
41
|
+
onChange={onChange}
|
|
42
|
+
value={value ?? ''}
|
|
43
|
+
invalid={invalid}
|
|
44
|
+
error={error}
|
|
45
|
+
disabled={element.disabled ?? !enable}
|
|
46
|
+
/>
|
|
38
47
|
)}
|
|
39
48
|
/>
|
|
40
49
|
: null
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
1
3
|
import React,{ FC } from 'react'
|
|
2
4
|
import { Controller } from 'react-hook-form'
|
|
3
5
|
import InputUpload from '../input-upload/input-upload'
|
|
4
6
|
import { useFieldRender } from '../../hooks/field-render'
|
|
5
7
|
import { IMakeUploadProps } from '../../interfaces/make-upload'
|
|
6
8
|
|
|
7
|
-
const MakeUpload : FC<IMakeUploadProps> = ({ element: { validation: { required, ...validation }, ...element }, ...props }) => {
|
|
8
|
-
const { render, enable } = useFieldRender({ ...props, element })
|
|
9
|
+
const MakeUpload : FC<IMakeUploadProps> = ({ element: { validation: { required, ...validation }, enableIf, renderIf, ...element }, ...props }) => {
|
|
10
|
+
const { render, enable } = useFieldRender({ ...props, element: { enableIf, renderIf, ...element} })
|
|
9
11
|
|
|
10
12
|
return (
|
|
11
13
|
render
|
|
@@ -13,17 +15,21 @@ const MakeUpload : FC<IMakeUploadProps> = ({ element: { validation: { required,
|
|
|
13
15
|
control={props.control}
|
|
14
16
|
name={element.name}
|
|
15
17
|
rules={{
|
|
16
|
-
required
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
required: {
|
|
19
|
+
value: required,
|
|
20
|
+
message: validation.message ?? ''
|
|
21
|
+
},
|
|
22
|
+
pattern: validation.regex ? {
|
|
23
|
+
value: validation.regex,
|
|
19
24
|
message: validation.message ?? ''
|
|
20
|
-
}
|
|
25
|
+
} : undefined,
|
|
26
|
+
...validation
|
|
21
27
|
}}
|
|
22
28
|
render={({ field: { onChange } }) => (
|
|
23
29
|
<InputUpload
|
|
24
|
-
|
|
25
|
-
disabled={element.disabled ?? !enable}
|
|
30
|
+
{...element}
|
|
26
31
|
onChange={onChange}
|
|
32
|
+
disabled={element.disabled ?? !enable}
|
|
27
33
|
/>
|
|
28
34
|
)}
|
|
29
35
|
/>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import React, { useMemo } from "react"
|
|
4
|
+
import { createContext } from "react"
|
|
5
|
+
import { IComponentState, IComponentStateProps } from "../../interfaces/component-state"
|
|
6
|
+
|
|
7
|
+
export const ComponentStateContext = createContext<IComponentState>({} as IComponentState)
|
|
8
|
+
|
|
9
|
+
export const ComponentState = ({ children, components }: IComponentStateProps) => {
|
|
10
|
+
|
|
11
|
+
const value: IComponentState = useMemo(() => components, [])
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<ComponentStateContext.Provider value={value}>
|
|
15
|
+
{children}
|
|
16
|
+
</ComponentStateContext.Provider>
|
|
17
|
+
)
|
|
18
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
'use client'
|
|
2
|
+
|
|
2
3
|
import { useCallback, useMemo, useState } from 'react'
|
|
3
4
|
import { IField, IFieldProps } from '../interfaces/field'
|
|
4
5
|
import { IOption } from '../interfaces/option'
|
|
@@ -19,11 +20,11 @@ export interface IFieldRender {
|
|
|
19
20
|
liveSearching?: boolean;
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
export interface IFieldRenderProps extends Pick<IFieldProps, 'setValue'|'unregister'> {
|
|
23
|
-
element: Partial<Pick<IField, 'enableIf'|'renderIf'|'name' >> & Partial<Record<'liveData', IModalLiveDataCondition>>
|
|
23
|
+
export interface IFieldRenderProps extends Pick<IFieldProps, 'setValue' | 'unregister'> {
|
|
24
|
+
element: Partial<Pick<IField, 'enableIf' | 'renderIf' | 'name' >> & Partial<Record<'liveData', IModalLiveDataCondition>>
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
export const useFieldRender = ({element, setValue, unregister}: IFieldRenderProps): IFieldRender => {
|
|
27
|
+
export const useFieldRender = ({ element, setValue, unregister }: IFieldRenderProps): IFieldRender => {
|
|
27
28
|
const [render, setRender] = useState<boolean|null>(null)
|
|
28
29
|
const [enable, setEnable] = useState<boolean|null>(null)
|
|
29
30
|
const [liveSearching, setLiveSearching] = useState<boolean>(false)
|
|
@@ -76,13 +77,13 @@ export const useFieldRender = ({element, setValue, unregister}: IFieldRenderProp
|
|
|
76
77
|
const fieldValidValue: boolean = targetField !== undefined && targetField !== null && targetField !== ''
|
|
77
78
|
|
|
78
79
|
if (renderCondition && renderConditionList.includes(key) && fieldValidValue) {
|
|
79
|
-
const renderStatus: boolean = (element.renderIf as IModalRenderCondition)[key]
|
|
80
|
+
const renderStatus: boolean = (element.renderIf as IModalRenderCondition)[key]!.includes(targetField) || (element.renderIf as IModalRenderCondition)[key]!.includes('*')
|
|
80
81
|
if (render !== renderStatus) {
|
|
81
82
|
setRender(renderStatus)
|
|
82
83
|
if(!renderStatus) unregister(element.name as string)
|
|
83
84
|
}
|
|
84
85
|
} else if (enableCondition && enableConditionList.includes(key) && fieldValidValue) {
|
|
85
|
-
const enableStatus: boolean = (element.enableIf as IModalRenderCondition)[key]
|
|
86
|
+
const enableStatus: boolean = (element.enableIf as IModalRenderCondition)[key]!.includes(targetField) || (element.enableIf as IModalRenderCondition)[key]!.includes('*')
|
|
86
87
|
if (enable !== enableStatus) setEnable(enableStatus)
|
|
87
88
|
}
|
|
88
89
|
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import { FC, PropsWithChildren } from "react"
|
|
3
|
+
import { FieldError } from "react-hook-form"
|
|
4
|
+
import { IOption } from "./option"
|
|
5
|
+
import { IMakeInput } from "./make-input"
|
|
6
|
+
import { IMakeButton } from "./make-button"
|
|
7
|
+
import { IMakeSelect } from "./make-select"
|
|
8
|
+
import { IMakeTextarea } from "./make-textarea"
|
|
9
|
+
import { IMakeToggle } from "./make-toggle"
|
|
10
|
+
|
|
11
|
+
export interface IComponentAditionalProps {
|
|
12
|
+
onChange: (...event: any[]) => void
|
|
13
|
+
value: any
|
|
14
|
+
invalid: boolean
|
|
15
|
+
error?: FieldError
|
|
16
|
+
liveSearching?: boolean
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface IComponentState {
|
|
20
|
+
ModalButtonCancel: FC<Omit<IMakeButton, 'elementType'>>
|
|
21
|
+
ModalButtonAction: FC<Omit<IMakeButton, 'elementType'>>
|
|
22
|
+
Button: FC<Omit<IMakeButton, 'elementType'>>
|
|
23
|
+
//Description: FC<Omit<IMakeDescription, 'elementType'>>
|
|
24
|
+
Input: FC<Omit<IMakeInput, 'elementType' | 'validation' |'renderIf' | 'enableIf'> & IComponentAditionalProps>
|
|
25
|
+
Select: FC<Omit<IMakeSelect, 'elementType' | 'validation' |'renderIf' | 'enableIf'> & IComponentAditionalProps & Record<'options', Array<IOption>>>
|
|
26
|
+
Textarea: FC<Omit<IMakeTextarea, 'elementType' | 'validation' |'renderIf' | 'enableIf'> & IComponentAditionalProps>
|
|
27
|
+
Toggle: FC<Omit<IMakeToggle, 'elementType' | 'validation' |'renderIf' | 'enableIf'> & IComponentAditionalProps>
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface IComponentStateProps extends PropsWithChildren {
|
|
31
|
+
components: IComponentState
|
|
32
|
+
}
|
|
33
|
+
|
package/src/interfaces/field.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
1
2
|
import { CSSProperties } from 'react'
|
|
2
3
|
import { Control, FieldValues, UseFormSetValue, UseFormUnregister, UseFormWatch } from 'react-hook-form'
|
|
4
|
+
import { IModalRenderCondition } from './modal'
|
|
3
5
|
|
|
4
6
|
export interface IValidationBase<T> {
|
|
5
7
|
value: T
|
|
@@ -10,10 +12,11 @@ export interface IField {
|
|
|
10
12
|
name: string
|
|
11
13
|
id?: string
|
|
12
14
|
label?: string
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
style?: CSSProperties
|
|
16
|
+
placeholder?: string
|
|
17
|
+
defaultValue?: any
|
|
18
|
+
renderIf?: IModalRenderCondition
|
|
19
|
+
enableIf?: IModalRenderCondition
|
|
17
20
|
validation: {
|
|
18
21
|
required: boolean
|
|
19
22
|
regex?: RegExp
|
|
@@ -24,12 +27,11 @@ export interface IField {
|
|
|
24
27
|
max?: IValidationBase<number | string>
|
|
25
28
|
}
|
|
26
29
|
disabled?: boolean
|
|
27
|
-
//required?: boolean
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
export interface IFieldProps {
|
|
31
|
-
control: Control<FieldValues, unknown
|
|
32
|
-
watch: UseFormWatch<FieldValues
|
|
33
|
-
setValue: UseFormSetValue<FieldValues
|
|
34
|
-
unregister: UseFormUnregister<FieldValues
|
|
33
|
+
control: Control<FieldValues, unknown>
|
|
34
|
+
watch: UseFormWatch<FieldValues>
|
|
35
|
+
setValue: UseFormSetValue<FieldValues>
|
|
36
|
+
unregister: UseFormUnregister<FieldValues>
|
|
35
37
|
}
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import { ChangeEvent, CSSProperties } from 'react'
|
|
2
2
|
|
|
3
3
|
export interface IFileResult {
|
|
4
|
-
name: string
|
|
5
|
-
size: number
|
|
4
|
+
name: string
|
|
5
|
+
size: number
|
|
6
6
|
data: string
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
export interface IInputUpload {
|
|
10
|
-
id?: string
|
|
11
|
-
value?: string
|
|
12
|
-
onChange: (event: ChangeEvent<HTMLInputElement> | IFileResult | FileList | null) => void
|
|
13
|
-
accept?:string
|
|
10
|
+
id?: string
|
|
11
|
+
value?: string
|
|
12
|
+
onChange: (event: ChangeEvent<HTMLInputElement> | IFileResult | FileList | null) => void
|
|
13
|
+
accept?:string
|
|
14
14
|
label?: string
|
|
15
15
|
helpText?: string
|
|
16
|
-
|
|
17
|
-
readAsArrayBuffer?: boolean
|
|
18
|
-
name: string
|
|
19
|
-
disabled?: boolean
|
|
20
|
-
read?: boolean
|
|
16
|
+
style?:CSSProperties
|
|
17
|
+
readAsArrayBuffer?: boolean
|
|
18
|
+
name: string
|
|
19
|
+
disabled?: boolean
|
|
20
|
+
read?: boolean
|
|
21
21
|
}
|