dynamic-modal 1.0.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-ES.md +75 -0
- package/README.md +75 -0
- package/eslint.config.mjs +14 -0
- package/examples/enable-if.ts +0 -0
- package/examples/live-data.ts +63 -0
- package/examples/render-if.ts +0 -0
- package/examples/simple.ts +76 -0
- package/index.ts +3 -0
- package/package.json +47 -0
- package/src/components/input-upload/input-upload.tsx +71 -0
- package/src/components/make-autocomplete/make-autocomplete.tsx +51 -0
- package/src/components/make-button/make-button.tsx +17 -0
- package/src/components/make-input/make-input.tsx +44 -0
- package/src/components/make-multi-select/make-multi-select.tsx +53 -0
- package/src/components/make-select/make-select.tsx +51 -0
- package/src/components/make-text/make-text.tsx +16 -0
- package/src/components/make-textarea/make-textarea.tsx +45 -0
- package/src/components/make-title/make-title.tsx +12 -0
- package/src/components/make-toggle/make-toggle.tsx +44 -0
- package/src/components/make-upload/make-upload.tsx +40 -0
- package/src/components/portal/portal.tsx +36 -0
- package/src/hooks/field-render.ts +104 -0
- package/src/hooks/modal-handler.ts +37 -0
- package/src/interfaces/field.ts +30 -0
- package/src/interfaces/input-upload.ts +36 -0
- package/src/interfaces/make-autocomplete.ts +15 -0
- package/src/interfaces/make-button.ts +20 -0
- package/src/interfaces/make-field-group.ts +13 -0
- package/src/interfaces/make-field.ts +14 -0
- package/src/interfaces/make-multi-select.ts +14 -0
- package/src/interfaces/make-select.ts +14 -0
- package/src/interfaces/make-text.ts +12 -0
- package/src/interfaces/make-textarea.ts +11 -0
- package/src/interfaces/make-title.ts +3 -0
- package/src/interfaces/make-toggle.ts +9 -0
- package/src/interfaces/make-upload.ts +13 -0
- package/src/interfaces/modal.ts +50 -0
- package/src/interfaces/option.ts +4 -0
- package/src/interfaces/portal.ts +8 -0
- package/src/modal.tsx +168 -0
- package/src/tools/general.ts +6 -0
- package/tsconfig.json +13 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import React, { FC, useEffect } from 'react'
|
|
2
|
+
import { Controller } from 'react-hook-form'
|
|
3
|
+
import { useFieldRender } from '../../hooks/field-render'
|
|
4
|
+
import { generateId } from '../../tools/general'
|
|
5
|
+
import { IMakeTextareaProps } from '../../interfaces/make-textarea'
|
|
6
|
+
import { Textarea } from '@nextui-org/react'
|
|
7
|
+
|
|
8
|
+
const MakeTextarea: FC<IMakeTextareaProps> = ({ element, ...props }) => {
|
|
9
|
+
const { render, enable, checkField } = useFieldRender({ ...props, element })
|
|
10
|
+
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
const subscription = props.watch((value, { name, type }) => checkField(value, { name, type }))
|
|
13
|
+
return () => subscription.unsubscribe()
|
|
14
|
+
}, [checkField, props, props.watch])
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
render
|
|
18
|
+
? <Controller
|
|
19
|
+
name={element.name}
|
|
20
|
+
control={props.control}
|
|
21
|
+
rules={{
|
|
22
|
+
required: element.validation.required,
|
|
23
|
+
pattern: {
|
|
24
|
+
value: element.validation.regex as RegExp ?? /(.*)/,
|
|
25
|
+
message: element.validation.message ?? ''
|
|
26
|
+
}
|
|
27
|
+
}}
|
|
28
|
+
render={({ field: { onChange, value }, fieldState: { invalid } }) => (
|
|
29
|
+
<Textarea
|
|
30
|
+
{...element}
|
|
31
|
+
disableAutosize
|
|
32
|
+
id={element.id ?? generateId()}
|
|
33
|
+
onChange={onChange}
|
|
34
|
+
label={element.label}
|
|
35
|
+
value={value ?? ''}
|
|
36
|
+
errorMessage={invalid ? (element.validation.message ?? '') : undefined}
|
|
37
|
+
disabled={element.disabled ?? !enable}
|
|
38
|
+
/>
|
|
39
|
+
)}
|
|
40
|
+
/>
|
|
41
|
+
: null
|
|
42
|
+
)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export default MakeTextarea
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React, { FC } from 'react'
|
|
2
|
+
import { IMakeTitle } from '../../interfaces/make-title'
|
|
3
|
+
|
|
4
|
+
const MakeTitle: FC<IMakeTitle> = ({ title }) => {
|
|
5
|
+
return (
|
|
6
|
+
<div className='flex text-center items-center justify-center text-xl'>
|
|
7
|
+
{title}
|
|
8
|
+
</div>
|
|
9
|
+
)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export default MakeTitle
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import React, { FC, useEffect } from 'react'
|
|
2
|
+
import { Controller } from 'react-hook-form'
|
|
3
|
+
import { useFieldRender } from '../../hooks/field-render'
|
|
4
|
+
import { IMakeToggleProps } from '../../interfaces/make-toggle'
|
|
5
|
+
import { Switch } from '@nextui-org/react'
|
|
6
|
+
import { generateId } from '../../tools/general'
|
|
7
|
+
|
|
8
|
+
const MakeToggle: FC<IMakeToggleProps> = (props) => {
|
|
9
|
+
const { render, enable, checkField } = useFieldRender(props)
|
|
10
|
+
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
const subscription = props.watch((value, { name, type }) => checkField(value, { name, type }))
|
|
13
|
+
return () => subscription.unsubscribe()
|
|
14
|
+
}, [checkField, props, props.watch])
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
render
|
|
18
|
+
? <Controller
|
|
19
|
+
control={props.control}
|
|
20
|
+
name={props.element.name}
|
|
21
|
+
rules={{
|
|
22
|
+
required: props.element.validation.required,
|
|
23
|
+
pattern: {
|
|
24
|
+
value: props.element.validation.regex as RegExp ?? /(.*)/,
|
|
25
|
+
message: props.element.validation.message ?? ''
|
|
26
|
+
}
|
|
27
|
+
}}
|
|
28
|
+
render={({ field: { onChange, value } }) => (
|
|
29
|
+
<Switch
|
|
30
|
+
{...props.element}
|
|
31
|
+
id={props.element.id ?? generateId()}
|
|
32
|
+
isSelected={value}
|
|
33
|
+
onValueChange={onChange}
|
|
34
|
+
isDisabled={props.element.disabled ?? !enable}
|
|
35
|
+
>
|
|
36
|
+
{props.element.label}
|
|
37
|
+
</Switch>
|
|
38
|
+
)}
|
|
39
|
+
/>
|
|
40
|
+
: null
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export default MakeToggle
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import React,{ FC } from 'react'
|
|
2
|
+
import { Controller } from 'react-hook-form'
|
|
3
|
+
import InputUpload from '../input-upload/input-upload'
|
|
4
|
+
import { useFieldRender } from '../../hooks/field-render'
|
|
5
|
+
import { IMakeUploadProps } from '../../interfaces/make-upload'
|
|
6
|
+
|
|
7
|
+
const MakeUpload : FC<IMakeUploadProps> = (props) => {
|
|
8
|
+
const { render, enable } = useFieldRender(props)
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
render
|
|
12
|
+
? <Controller
|
|
13
|
+
control={props.control}
|
|
14
|
+
name={props.element.name}
|
|
15
|
+
rules={{
|
|
16
|
+
required: props.element.validation.required,
|
|
17
|
+
pattern: {
|
|
18
|
+
value: props.element.validation.regex as RegExp ?? /(.*)/,
|
|
19
|
+
message: props.element.validation.message ?? ''
|
|
20
|
+
}
|
|
21
|
+
}}
|
|
22
|
+
render={({ field: { onChange } }) => (
|
|
23
|
+
<InputUpload
|
|
24
|
+
id={props.element.id}
|
|
25
|
+
name={props.element.name}
|
|
26
|
+
disabled={props.element.disabled ?? !enable}
|
|
27
|
+
onChange={onChange}
|
|
28
|
+
label={props.element.label}
|
|
29
|
+
helpText={props.element.helpText}
|
|
30
|
+
style={props.element.styles}
|
|
31
|
+
accept={props.element.accept}
|
|
32
|
+
read={props.element.read}
|
|
33
|
+
/>
|
|
34
|
+
)}
|
|
35
|
+
/>
|
|
36
|
+
: null
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export default MakeUpload
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import React, { useRef, useEffect, useState, FC } from 'react'
|
|
3
|
+
import { createPortal } from 'react-dom'
|
|
4
|
+
import { IPortal } from '../../interfaces/portal'
|
|
5
|
+
|
|
6
|
+
export const Portal: FC<IPortal> = (props) => {
|
|
7
|
+
const ref = useRef<Element | null>(null)
|
|
8
|
+
const [mounted, setMounted] = useState(false)
|
|
9
|
+
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
if (mounted && !props.portalOpen && props.closeTime > 0) {
|
|
12
|
+
const timeoutId = setTimeout(() => {
|
|
13
|
+
setMounted(false)
|
|
14
|
+
ref.current = null
|
|
15
|
+
}, props.closeTime)
|
|
16
|
+
|
|
17
|
+
return () => clearTimeout(timeoutId)
|
|
18
|
+
} else if (mounted && !props.portalOpen) {
|
|
19
|
+
setMounted(false)
|
|
20
|
+
ref.current = null
|
|
21
|
+
} else if (!mounted && props.portalOpen) {
|
|
22
|
+
ref.current = document.querySelector<HTMLElement>(props.portalTag ?? '#portal')
|
|
23
|
+
setMounted(true)
|
|
24
|
+
}
|
|
25
|
+
}, [mounted, props.closeTime, props.portalOpen, props.portalTag])
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
mounted && ref.current
|
|
29
|
+
? createPortal(
|
|
30
|
+
<div className='transition-all delay-100 fixed top-0 left-0 w-full h-full grid place-items-center bg-black bg-opacity-40 z-20'>
|
|
31
|
+
{props.children}
|
|
32
|
+
</div>
|
|
33
|
+
, ref.current)
|
|
34
|
+
: null
|
|
35
|
+
)
|
|
36
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import { useCallback, useMemo, useState } from 'react'
|
|
3
|
+
import { IField, IFieldProps } from '../interfaces/field'
|
|
4
|
+
import { IOption } from '../interfaces/option'
|
|
5
|
+
import { IModalLiveDataCondition, IModalRenderCondition } from '../interfaces/modal'
|
|
6
|
+
|
|
7
|
+
export type IFormData = Record<string, unknown>
|
|
8
|
+
|
|
9
|
+
export interface IWatchEvent {
|
|
10
|
+
name: string | undefined;
|
|
11
|
+
type: string | undefined;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface IFieldRender {
|
|
15
|
+
render: boolean | null;
|
|
16
|
+
enable: boolean | null;
|
|
17
|
+
checkField: (formData: IFormData, { name, type }: IWatchEvent) => void;
|
|
18
|
+
liveData?: Array<IOption>;
|
|
19
|
+
liveSearching?: boolean;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface IFieldRenderProps extends Pick<IFieldProps, 'setValue'> {
|
|
23
|
+
element: Partial<Pick<IField, 'enableIf'|'renderIf'|'name' >> & Partial<Record<'liveData', IModalLiveDataCondition>>
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const useFieldRender = (props: IFieldRenderProps): IFieldRender => {
|
|
27
|
+
const [render, setRender] = useState<boolean|null>(null)
|
|
28
|
+
const [enable, setEnable] = useState<boolean|null>(null)
|
|
29
|
+
const [liveSearching, setLiveSearching] = useState<boolean>(false)
|
|
30
|
+
const [liveData, setLiveData] = useState<Array<IOption> | undefined>(undefined)
|
|
31
|
+
|
|
32
|
+
const renderCondition = useMemo<boolean>(
|
|
33
|
+
() => {
|
|
34
|
+
const isRender: boolean = props.element.renderIf !== undefined
|
|
35
|
+
if (render === null) setRender(!isRender)
|
|
36
|
+
return isRender
|
|
37
|
+
}, [props.element.renderIf, render]
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
const enableCondition = useMemo<boolean>(
|
|
41
|
+
() => {
|
|
42
|
+
const isEnable: boolean = props.element.enableIf !== undefined
|
|
43
|
+
if (enable === null) setEnable(!isEnable)
|
|
44
|
+
return isEnable
|
|
45
|
+
}, [props.element.enableIf, enable]
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
const liveDataCondition = useMemo<boolean>(
|
|
49
|
+
() => {
|
|
50
|
+
return props.element.liveData !== undefined
|
|
51
|
+
}, [props.element.liveData]
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
const renderConditionList: string[] = useMemo(() => {
|
|
55
|
+
return renderCondition ? Object.keys(props.element.renderIf as IModalRenderCondition) : []
|
|
56
|
+
}, [props.element.renderIf, renderCondition])
|
|
57
|
+
|
|
58
|
+
const enableConditionList: string[] = useMemo(() => {
|
|
59
|
+
return enableCondition ? Object.keys(props.element.enableIf as IModalRenderCondition) : []
|
|
60
|
+
}, [enableCondition, props.element.enableIf])
|
|
61
|
+
|
|
62
|
+
const liveDataAction = useCallback(
|
|
63
|
+
async (field: string |number | Array<unknown>, formData: IFormData) => {
|
|
64
|
+
if (typeof field === 'string' && props.element.liveData?.action) {
|
|
65
|
+
const options = props.element.liveData.action(field, formData)
|
|
66
|
+
return options ?? []
|
|
67
|
+
}
|
|
68
|
+
return [] as Array<IOption>
|
|
69
|
+
}, [props.element.liveData]
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
const checkField = useCallback(
|
|
73
|
+
async (formData: IFormData, { name }: IWatchEvent) => {
|
|
74
|
+
const key: string = name ?? ''
|
|
75
|
+
const targetField = formData[key] as string | number
|
|
76
|
+
|
|
77
|
+
if (renderCondition && renderConditionList.includes(key)) {
|
|
78
|
+
const renderStatus: boolean = (props.element.renderIf as IModalRenderCondition)[key].includes(targetField)
|
|
79
|
+
if (render !== renderStatus) setRender(renderStatus)
|
|
80
|
+
} else if (enableCondition && enableConditionList.includes(key)) {
|
|
81
|
+
const enableStatus: boolean = (props.element.enableIf as IModalRenderCondition)[key].includes(targetField)
|
|
82
|
+
if (enable !== enableStatus) setEnable(enableStatus)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (liveDataCondition && key === props.element.liveData?.condition) {
|
|
86
|
+
if (targetField) {
|
|
87
|
+
setLiveSearching(true)
|
|
88
|
+
const options: Array<IOption> = await liveDataAction(targetField, formData)
|
|
89
|
+
if (liveData && JSON.stringify(liveData) !== JSON.stringify(options)) { props.setValue(props.element.name as string, options) }
|
|
90
|
+
setLiveData(options)
|
|
91
|
+
setLiveSearching(false)
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}, [enable, enableCondition, enableConditionList, liveData, liveDataAction, liveDataCondition, props, render, renderCondition, renderConditionList]
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
return {
|
|
98
|
+
render,
|
|
99
|
+
enable,
|
|
100
|
+
checkField,
|
|
101
|
+
liveData,
|
|
102
|
+
liveSearching
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import { useState } from 'react'
|
|
3
|
+
import { IModal, IModalConfigProps } from '../interfaces/modal'
|
|
4
|
+
|
|
5
|
+
interface IModalHandler {
|
|
6
|
+
openModal: (config: IModalConfigProps) => void
|
|
7
|
+
modalProps: IModal
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function useModalHandler (): IModalHandler {
|
|
11
|
+
const initialState: IModalHandler = {
|
|
12
|
+
modalProps: {
|
|
13
|
+
config: {} as IModalConfigProps,
|
|
14
|
+
close: () => {},
|
|
15
|
+
open: false,
|
|
16
|
+
},
|
|
17
|
+
openModal: () => {},
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const [modalConfig, setModalConfig] = useState<IModalHandler>(initialState)
|
|
21
|
+
|
|
22
|
+
const openModal = (config: IModalConfigProps) => {
|
|
23
|
+
if (!config) {
|
|
24
|
+
alert(`¡WARNING! this modal was not returned config, please check before use`)
|
|
25
|
+
return
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
setModalConfig({ openModal, modalProps: { config, open: true, close } })
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const closeModal = () => setModalConfig(initialState)
|
|
32
|
+
|
|
33
|
+
return {
|
|
34
|
+
openModal,
|
|
35
|
+
modalProps: { ...modalConfig.modalProps, close: closeModal },
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { CSSProperties } from 'react'
|
|
2
|
+
import { Control, FieldValues, UseFormSetValue, UseFormWatch } from 'react-hook-form'
|
|
3
|
+
import { IOption } from './option'
|
|
4
|
+
|
|
5
|
+
export interface IFieldLiveData {
|
|
6
|
+
action: (data: string, ...args: unknown[]) => Promise<Array<IOption>>;
|
|
7
|
+
condition: string
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface IField {
|
|
11
|
+
name: string
|
|
12
|
+
id?: string
|
|
13
|
+
label?: string
|
|
14
|
+
styles?: CSSProperties
|
|
15
|
+
defaultValue?: string
|
|
16
|
+
renderIf?: Record<string, Array<string | number>>
|
|
17
|
+
enableIf?: Record<string, Array<string | number>>
|
|
18
|
+
validation: {
|
|
19
|
+
required: boolean
|
|
20
|
+
regex?: RegExp
|
|
21
|
+
message?: string
|
|
22
|
+
}
|
|
23
|
+
disabled?: boolean
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface IFieldProps {
|
|
27
|
+
control: Control<FieldValues, unknown>;
|
|
28
|
+
watch: UseFormWatch<FieldValues>;
|
|
29
|
+
setValue: UseFormSetValue<FieldValues>
|
|
30
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { ChangeEvent, CSSProperties } from 'react'
|
|
2
|
+
|
|
3
|
+
export interface IFileResult {
|
|
4
|
+
name: string;
|
|
5
|
+
size: number;
|
|
6
|
+
data: string
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
export interface IFile {
|
|
11
|
+
data?: string
|
|
12
|
+
name: string;
|
|
13
|
+
size: number;
|
|
14
|
+
}
|
|
15
|
+
export interface IInputState {
|
|
16
|
+
state: boolean;
|
|
17
|
+
file: IFile
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface IInputStorage {
|
|
21
|
+
setData: (file: IInputState) => void;
|
|
22
|
+
clearFuntion: () => void;
|
|
23
|
+
}
|
|
24
|
+
export interface IInputUpload {
|
|
25
|
+
id?: string;
|
|
26
|
+
value?: string;
|
|
27
|
+
onChange: (event: ChangeEvent<HTMLInputElement> | IFileResult | FileList | null) => void;
|
|
28
|
+
accept?:string;
|
|
29
|
+
label?: string
|
|
30
|
+
helpText?: string
|
|
31
|
+
clearfunction?: () => void;
|
|
32
|
+
style?:CSSProperties;
|
|
33
|
+
name: string;
|
|
34
|
+
disabled?: boolean;
|
|
35
|
+
read?: boolean;
|
|
36
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { IField, IFieldProps } from './field'
|
|
2
|
+
import { IModalLiveDataCondition } from './modal'
|
|
3
|
+
import { IOption } from './option'
|
|
4
|
+
|
|
5
|
+
export interface IMakeAutoComplete extends IField {
|
|
6
|
+
elementType: 'autocomplete'
|
|
7
|
+
options: Array<IOption>
|
|
8
|
+
defaultOption?: boolean
|
|
9
|
+
defaultOptionName?: string
|
|
10
|
+
liveData?: IModalLiveDataCondition
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface IMakeAutoCompleteProps extends IFieldProps {
|
|
14
|
+
element: IMakeAutoComplete
|
|
15
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { CSSProperties } from 'react'
|
|
2
|
+
import { IFieldProps } from './field'
|
|
3
|
+
|
|
4
|
+
export interface IMakeButton {
|
|
5
|
+
elementType: 'button';
|
|
6
|
+
disabled?: boolean
|
|
7
|
+
className?: string;
|
|
8
|
+
variant?: 'solid' | 'light' | 'flat' | 'bordered' | 'faded' | 'shadow' | 'ghost'
|
|
9
|
+
text?: string;
|
|
10
|
+
type?: 'button' | 'submit' | 'reset';
|
|
11
|
+
onClick?: () => void;
|
|
12
|
+
iconName?: string;
|
|
13
|
+
iconSize?: number | string;
|
|
14
|
+
iconClassName?: CSSProperties;
|
|
15
|
+
color?: 'primary' | 'secondary' | 'default' | 'success' | 'warning' | 'danger'
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface IMakeButtonProps extends IFieldProps {
|
|
19
|
+
element: IMakeButton
|
|
20
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { CSSProperties } from 'react'
|
|
2
|
+
import { IFieldProps } from './field'
|
|
3
|
+
import { IModalField } from './modal'
|
|
4
|
+
|
|
5
|
+
export interface IMakeFieldGroup {
|
|
6
|
+
elementType: 'group';
|
|
7
|
+
groups: Array<IModalField>;
|
|
8
|
+
style?: CSSProperties;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface IMakeFieldGroupProps extends IFieldProps {
|
|
12
|
+
element: IMakeFieldGroup;
|
|
13
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { HTMLInputTypeAttribute } from 'react'
|
|
2
|
+
import { IField, IFieldProps } from './field'
|
|
3
|
+
|
|
4
|
+
export interface IMakeInput extends IField {
|
|
5
|
+
elementType: 'input'
|
|
6
|
+
placeHolder?: string
|
|
7
|
+
min?: string
|
|
8
|
+
max?: string
|
|
9
|
+
type?: HTMLInputTypeAttribute
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface IMakeInputProps extends IFieldProps {
|
|
13
|
+
element: IMakeInput
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { IOption } from './option'
|
|
2
|
+
import { IField, IFieldProps } from './field'
|
|
3
|
+
import { IModalLiveDataCondition } from './modal'
|
|
4
|
+
|
|
5
|
+
export interface IMakeMultiSelect extends Omit<IField, 'defaultValue'> {
|
|
6
|
+
elementType: 'multiselect';
|
|
7
|
+
options: Array<IOption>;
|
|
8
|
+
liveData?: IModalLiveDataCondition;
|
|
9
|
+
defaultValue?: Array<string>
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface IMakeMultiSelectProps extends IFieldProps {
|
|
13
|
+
element: IMakeMultiSelect
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { IField, IFieldProps } from './field'
|
|
2
|
+
import { IModalLiveDataCondition } from './modal'
|
|
3
|
+
|
|
4
|
+
export interface IMakeSelect extends IField {
|
|
5
|
+
elementType: 'select'
|
|
6
|
+
options: Array<Record<'id'|'name', string>>
|
|
7
|
+
defaultOption?: boolean
|
|
8
|
+
defaultOptionName?: string
|
|
9
|
+
liveData?: IModalLiveDataCondition
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface IMakeSelectProps extends IFieldProps {
|
|
13
|
+
element: IMakeSelect
|
|
14
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { CSSProperties } from 'react'
|
|
2
|
+
import { IFieldProps } from './field'
|
|
3
|
+
|
|
4
|
+
export interface IMakeText {
|
|
5
|
+
elementType: 'text'
|
|
6
|
+
text: string
|
|
7
|
+
styles?: CSSProperties
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface IMakeTextProps extends IFieldProps {
|
|
11
|
+
element: IMakeText
|
|
12
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
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
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface IMakeUploadProps extends IFieldProps {
|
|
12
|
+
element: IMakeUpload
|
|
13
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { CSSProperties } from 'react'
|
|
2
|
+
import { IMakeSelect } from './make-select'
|
|
3
|
+
import { IMakeInput } from './make-field'
|
|
4
|
+
import { IMakeTextarea } from './make-textarea'
|
|
5
|
+
import { IMakeToggle } from './make-toggle'
|
|
6
|
+
import { IMakeMultiSelect } from './make-multi-select'
|
|
7
|
+
import { IMakeText } from './make-text'
|
|
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
|
+
import { IMakeAutoComplete } from './make-autocomplete'
|
|
13
|
+
|
|
14
|
+
export type IModalField = IMakeSelect | IMakeInput | IMakeFieldGroup | IMakeTextarea | IMakeToggle | IMakeMultiSelect | IMakeText | IMakeUpload | IMakeButton | IMakeAutoComplete
|
|
15
|
+
|
|
16
|
+
export type IFormField = IMakeSelect | IMakeInput | IMakeTextarea | IMakeToggle | IMakeMultiSelect
|
|
17
|
+
|
|
18
|
+
export type IModalRenderCondition = Record<string, Array<string | number>>
|
|
19
|
+
|
|
20
|
+
export type IModalLiveDataCondition = {
|
|
21
|
+
action: (data: string, ...args: never[]) => Promise<Array<IOption>>;
|
|
22
|
+
condition: string
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface IModalConfigProps {
|
|
26
|
+
fields: Array<IModalField>
|
|
27
|
+
title: string
|
|
28
|
+
action: {
|
|
29
|
+
name: string
|
|
30
|
+
action?: (data: never) => void
|
|
31
|
+
hide?: boolean
|
|
32
|
+
}
|
|
33
|
+
cancel?: {
|
|
34
|
+
name?: string;
|
|
35
|
+
action?: () => void
|
|
36
|
+
hide?: boolean;
|
|
37
|
+
}
|
|
38
|
+
reservedData?: Record<string, string | number>
|
|
39
|
+
styles?: CSSProperties;
|
|
40
|
+
overFlowBody?: string | number
|
|
41
|
+
minHeightBody?: string | number
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export type IModalConfigLoader<T = never, D = never> = (props: T, action: (modalResult: D) => void) => IModalConfigProps
|
|
45
|
+
|
|
46
|
+
export interface IModal {
|
|
47
|
+
open: boolean;
|
|
48
|
+
close: () => void
|
|
49
|
+
config: IModalConfigProps
|
|
50
|
+
}
|