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
package/examples/render-if.ts
CHANGED
|
@@ -1,129 +1,129 @@
|
|
|
1
|
-
|
|
2
|
-
import { IModalConfigLoader } from '../src/interfaces/modal'
|
|
3
|
-
|
|
4
|
-
export type IncomingProps = object
|
|
5
|
-
|
|
6
|
-
type ResultProps = Record<'optionId', string> & Partial<Record<'input1ReadOnly' | 'input1WriteValue' | 'input2ReadOnly' | 'input2WriteValue', string>>
|
|
7
|
-
|
|
8
|
-
export interface IRenderIfModal {
|
|
9
|
-
default: IModalConfigLoader<IncomingProps, ResultProps>
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const renderIfModal: IRenderIfModal = {
|
|
13
|
-
default: (props, action) => {
|
|
14
|
-
return {
|
|
15
|
-
reservedData: {}, //Put here any data that you want store and receive into modal output
|
|
16
|
-
fields: [ //Put here any elements for render into modal
|
|
17
|
-
{
|
|
18
|
-
elementType: 'select',
|
|
19
|
-
label: 'option',
|
|
20
|
-
defaultValue: '0',
|
|
21
|
-
options: [
|
|
22
|
-
{
|
|
23
|
-
id: '0',
|
|
24
|
-
name:'Select...'
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
id: '1',
|
|
28
|
-
name:'Option 1'
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
id: '2',
|
|
32
|
-
name:'Option 2'
|
|
33
|
-
}
|
|
34
|
-
],
|
|
35
|
-
name: 'optionId', //Element to be observed
|
|
36
|
-
validation: {
|
|
37
|
-
required: true,
|
|
38
|
-
message: 'Please select a valid option'
|
|
39
|
-
}
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
elementType: 'group', //Put here groups of element into same line and customize using styles
|
|
43
|
-
groups: [
|
|
44
|
-
{
|
|
45
|
-
elementType: 'input',
|
|
46
|
-
label: 'Input 1 (Read)',
|
|
47
|
-
name: 'input1ReadOnly',
|
|
48
|
-
disabled: true,
|
|
49
|
-
styles: {
|
|
50
|
-
width: '50%'
|
|
51
|
-
},
|
|
52
|
-
validation: {
|
|
53
|
-
required: false
|
|
54
|
-
},
|
|
55
|
-
//Define render condition (element will be show when value of element observed match with array condition)
|
|
56
|
-
renderIf: {
|
|
57
|
-
optionId: ['1']
|
|
58
|
-
}
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
elementType: 'input',
|
|
62
|
-
label: 'Input 1',
|
|
63
|
-
name: 'input1WriteValue',
|
|
64
|
-
styles: {
|
|
65
|
-
width: '50%'
|
|
66
|
-
},
|
|
67
|
-
validation: {
|
|
68
|
-
required: true,
|
|
69
|
-
message: `Write a valid input value`
|
|
70
|
-
},
|
|
71
|
-
//Define render condition (element will be show when value of element observed match with array condition)
|
|
72
|
-
renderIf: {
|
|
73
|
-
optionId: ['1']
|
|
74
|
-
}
|
|
75
|
-
},
|
|
76
|
-
]
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
elementType: 'group', //Put here groups of element into same line and customize using styles
|
|
80
|
-
groups: [
|
|
81
|
-
{
|
|
82
|
-
elementType: 'input',
|
|
83
|
-
label: 'Input 2 (Read)',
|
|
84
|
-
name: 'input2ReadOnly',
|
|
85
|
-
disabled: true,
|
|
86
|
-
styles: {
|
|
87
|
-
width: '50%'
|
|
88
|
-
},
|
|
89
|
-
validation: {
|
|
90
|
-
required: false
|
|
91
|
-
},
|
|
92
|
-
//Define render condition (element will be show when value of element observed match with array condition)
|
|
93
|
-
renderIf: {
|
|
94
|
-
optionId: ['2']
|
|
95
|
-
}
|
|
96
|
-
},
|
|
97
|
-
{
|
|
98
|
-
elementType: 'input',
|
|
99
|
-
label: 'Input 2',
|
|
100
|
-
name: 'input2WriteValue',
|
|
101
|
-
styles: {
|
|
102
|
-
width: '50%'
|
|
103
|
-
},
|
|
104
|
-
validation: {
|
|
105
|
-
required: true,
|
|
106
|
-
message: `Write a valid input value`
|
|
107
|
-
},
|
|
108
|
-
//Define render condition (element will be show when value of element observed match with array condition)
|
|
109
|
-
renderIf: {
|
|
110
|
-
optionId: ['2']
|
|
111
|
-
}
|
|
112
|
-
},
|
|
113
|
-
]
|
|
114
|
-
},
|
|
115
|
-
],
|
|
116
|
-
style: { // Put here styles for modal like height or width
|
|
117
|
-
width: '500px'
|
|
118
|
-
},
|
|
119
|
-
title: `Title of enable if modal`, //Title of modal
|
|
120
|
-
out: action, //Function to receive data from modal
|
|
121
|
-
actions: { //Actions of modal, all props that you define here will be pass to ModalButtonCancel and ModalButtonAction components in your ComponentState
|
|
122
|
-
action: { text:'Action', color: 'Primary' },
|
|
123
|
-
cancel: { text: 'Cancel', color: 'Danger' }
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
1
|
+
|
|
2
|
+
import { IModalConfigLoader } from '../src/interfaces/modal'
|
|
3
|
+
|
|
4
|
+
export type IncomingProps = object
|
|
5
|
+
|
|
6
|
+
type ResultProps = Record<'optionId', string> & Partial<Record<'input1ReadOnly' | 'input1WriteValue' | 'input2ReadOnly' | 'input2WriteValue', string>>
|
|
7
|
+
|
|
8
|
+
export interface IRenderIfModal {
|
|
9
|
+
default: IModalConfigLoader<IncomingProps, ResultProps>
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const renderIfModal: IRenderIfModal = {
|
|
13
|
+
default: (props, action) => {
|
|
14
|
+
return {
|
|
15
|
+
reservedData: {}, //Put here any data that you want store and receive into modal output
|
|
16
|
+
fields: [ //Put here any elements for render into modal
|
|
17
|
+
{
|
|
18
|
+
elementType: 'select',
|
|
19
|
+
label: 'option',
|
|
20
|
+
defaultValue: '0',
|
|
21
|
+
options: [
|
|
22
|
+
{
|
|
23
|
+
id: '0',
|
|
24
|
+
name:'Select...'
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
id: '1',
|
|
28
|
+
name:'Option 1'
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
id: '2',
|
|
32
|
+
name:'Option 2'
|
|
33
|
+
}
|
|
34
|
+
],
|
|
35
|
+
name: 'optionId', //Element to be observed
|
|
36
|
+
validation: {
|
|
37
|
+
required: true,
|
|
38
|
+
message: 'Please select a valid option'
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
elementType: 'group', //Put here groups of element into same line and customize using styles
|
|
43
|
+
groups: [
|
|
44
|
+
{
|
|
45
|
+
elementType: 'input',
|
|
46
|
+
label: 'Input 1 (Read)',
|
|
47
|
+
name: 'input1ReadOnly',
|
|
48
|
+
disabled: true,
|
|
49
|
+
styles: {
|
|
50
|
+
width: '50%'
|
|
51
|
+
},
|
|
52
|
+
validation: {
|
|
53
|
+
required: false
|
|
54
|
+
},
|
|
55
|
+
//Define render condition (element will be show when value of element observed match with array condition)
|
|
56
|
+
renderIf: {
|
|
57
|
+
optionId: ['1']
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
elementType: 'input',
|
|
62
|
+
label: 'Input 1',
|
|
63
|
+
name: 'input1WriteValue',
|
|
64
|
+
styles: {
|
|
65
|
+
width: '50%'
|
|
66
|
+
},
|
|
67
|
+
validation: {
|
|
68
|
+
required: true,
|
|
69
|
+
message: `Write a valid input value`
|
|
70
|
+
},
|
|
71
|
+
//Define render condition (element will be show when value of element observed match with array condition)
|
|
72
|
+
renderIf: {
|
|
73
|
+
optionId: ['1']
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
]
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
elementType: 'group', //Put here groups of element into same line and customize using styles
|
|
80
|
+
groups: [
|
|
81
|
+
{
|
|
82
|
+
elementType: 'input',
|
|
83
|
+
label: 'Input 2 (Read)',
|
|
84
|
+
name: 'input2ReadOnly',
|
|
85
|
+
disabled: true,
|
|
86
|
+
styles: {
|
|
87
|
+
width: '50%'
|
|
88
|
+
},
|
|
89
|
+
validation: {
|
|
90
|
+
required: false
|
|
91
|
+
},
|
|
92
|
+
//Define render condition (element will be show when value of element observed match with array condition)
|
|
93
|
+
renderIf: {
|
|
94
|
+
optionId: ['2']
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
elementType: 'input',
|
|
99
|
+
label: 'Input 2',
|
|
100
|
+
name: 'input2WriteValue',
|
|
101
|
+
styles: {
|
|
102
|
+
width: '50%'
|
|
103
|
+
},
|
|
104
|
+
validation: {
|
|
105
|
+
required: true,
|
|
106
|
+
message: `Write a valid input value`
|
|
107
|
+
},
|
|
108
|
+
//Define render condition (element will be show when value of element observed match with array condition)
|
|
109
|
+
renderIf: {
|
|
110
|
+
optionId: ['2']
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
]
|
|
114
|
+
},
|
|
115
|
+
],
|
|
116
|
+
style: { // Put here styles for modal like height or width
|
|
117
|
+
width: '500px'
|
|
118
|
+
},
|
|
119
|
+
title: `Title of enable if modal`, //Title of modal
|
|
120
|
+
out: action, //Function to receive data from modal
|
|
121
|
+
actions: { //Actions of modal, all props that you define here will be pass to ModalButtonCancel and ModalButtonAction components in your ComponentState
|
|
122
|
+
action: { text:'Action', color: 'Primary' },
|
|
123
|
+
cancel: { text: 'Cancel', color: 'Danger' }
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
129
|
export default renderIfModal
|
package/examples/simple.ts
CHANGED
|
@@ -1,75 +1,75 @@
|
|
|
1
|
-
import { IModalConfigLoader } from '../src/interfaces/modal'
|
|
2
|
-
|
|
3
|
-
type IncomingProps = {
|
|
4
|
-
reserved: string
|
|
5
|
-
input1: string
|
|
6
|
-
store?: boolean
|
|
7
|
-
clear?: boolean
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
type ResultProps = IncomingProps
|
|
11
|
-
|
|
12
|
-
export interface ISimpleModal {
|
|
13
|
-
default: IModalConfigLoader<IncomingProps, ResultProps> //Define others modals if you want
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const simpleModal: ISimpleModal = {
|
|
17
|
-
default: (props, action) => {
|
|
18
|
-
return {
|
|
19
|
-
reservedData: { reserved: props.reserved }, //Put here any data that you want store and receive into modal output
|
|
20
|
-
fields: [ //Put here any elements for render into modal
|
|
21
|
-
{
|
|
22
|
-
elementType: 'input',
|
|
23
|
-
label: 'Input 1',
|
|
24
|
-
defaultValue: props.input1,
|
|
25
|
-
name: 'input1',
|
|
26
|
-
validation: {
|
|
27
|
-
required: true,
|
|
28
|
-
message: 'This field is required',
|
|
29
|
-
regex: undefined //Use regex for custom validation
|
|
30
|
-
}
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
elementType: 'group', //Put here groups of element into same line and customize using styles
|
|
34
|
-
groups: [
|
|
35
|
-
{
|
|
36
|
-
elementType: 'toggle',
|
|
37
|
-
label: 'Store',
|
|
38
|
-
defaultValue: `${props.store ?? false}`,
|
|
39
|
-
name: 'store',
|
|
40
|
-
styles: {
|
|
41
|
-
width: '50%'
|
|
42
|
-
},
|
|
43
|
-
validation: {
|
|
44
|
-
required: false
|
|
45
|
-
}
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
elementType: 'toggle',
|
|
49
|
-
label: 'Clear',
|
|
50
|
-
defaultValue: `${props.clear ?? false}`,
|
|
51
|
-
name: 'clear',
|
|
52
|
-
styles: {
|
|
53
|
-
width: '50%'
|
|
54
|
-
},
|
|
55
|
-
validation: {
|
|
56
|
-
required: false
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
]
|
|
60
|
-
},
|
|
61
|
-
],
|
|
62
|
-
style: { // Put here styles for modal like height or width
|
|
63
|
-
width: '500px'
|
|
64
|
-
},
|
|
65
|
-
title: `Title of enable if modal`, //Title of modal
|
|
66
|
-
out: action, //Function to receive data from modal
|
|
67
|
-
actions: { //Actions of modal, all props that you define here will be pass to ModalButtonCancel and ModalButtonAction components in your ComponentState
|
|
68
|
-
action: { text:'Action', color: 'Primary' },
|
|
69
|
-
cancel: { text: 'Cancel', color: 'Danger' }
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
1
|
+
import { IModalConfigLoader } from '../src/interfaces/modal'
|
|
2
|
+
|
|
3
|
+
type IncomingProps = {
|
|
4
|
+
reserved: string
|
|
5
|
+
input1: string
|
|
6
|
+
store?: boolean
|
|
7
|
+
clear?: boolean
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
type ResultProps = IncomingProps
|
|
11
|
+
|
|
12
|
+
export interface ISimpleModal {
|
|
13
|
+
default: IModalConfigLoader<IncomingProps, ResultProps> //Define others modals if you want
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const simpleModal: ISimpleModal = {
|
|
17
|
+
default: (props, action) => {
|
|
18
|
+
return {
|
|
19
|
+
reservedData: { reserved: props.reserved }, //Put here any data that you want store and receive into modal output
|
|
20
|
+
fields: [ //Put here any elements for render into modal
|
|
21
|
+
{
|
|
22
|
+
elementType: 'input',
|
|
23
|
+
label: 'Input 1',
|
|
24
|
+
defaultValue: props.input1,
|
|
25
|
+
name: 'input1',
|
|
26
|
+
validation: {
|
|
27
|
+
required: true,
|
|
28
|
+
message: 'This field is required',
|
|
29
|
+
regex: undefined //Use regex for custom validation
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
elementType: 'group', //Put here groups of element into same line and customize using styles
|
|
34
|
+
groups: [
|
|
35
|
+
{
|
|
36
|
+
elementType: 'toggle',
|
|
37
|
+
label: 'Store',
|
|
38
|
+
defaultValue: `${props.store ?? false}`,
|
|
39
|
+
name: 'store',
|
|
40
|
+
styles: {
|
|
41
|
+
width: '50%'
|
|
42
|
+
},
|
|
43
|
+
validation: {
|
|
44
|
+
required: false
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
elementType: 'toggle',
|
|
49
|
+
label: 'Clear',
|
|
50
|
+
defaultValue: `${props.clear ?? false}`,
|
|
51
|
+
name: 'clear',
|
|
52
|
+
styles: {
|
|
53
|
+
width: '50%'
|
|
54
|
+
},
|
|
55
|
+
validation: {
|
|
56
|
+
required: false
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
]
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
style: { // Put here styles for modal like height or width
|
|
63
|
+
width: '500px'
|
|
64
|
+
},
|
|
65
|
+
title: `Title of enable if modal`, //Title of modal
|
|
66
|
+
out: action, //Function to receive data from modal
|
|
67
|
+
actions: { //Actions of modal, all props that you define here will be pass to ModalButtonCancel and ModalButtonAction components in your ComponentState
|
|
68
|
+
action: { text:'Action', color: 'Primary' },
|
|
69
|
+
cancel: { text: 'Cancel', color: 'Danger' }
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
75
|
export default simpleModal
|
package/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
export { default as DynamicModal } from './src/modal'
|
|
3
|
-
export type { IModalConfigLoader, IModalConfigProps, IModalRenderCondition, IModalField, IModalLiveDataCondition } from './src/interfaces/modal'
|
|
4
|
-
export { useModalHandler } from './src/hooks/modal-handler'
|
|
5
|
-
export { ComponentState, ComponentStateContext } from './src/context/component/component-state'
|
|
1
|
+
'use client'
|
|
2
|
+
export { default as DynamicModal } from './src/modal'
|
|
3
|
+
export type { IModalConfigLoader, IModalConfigProps, IModalRenderCondition, IModalField, IModalLiveDataCondition } from './src/interfaces/modal'
|
|
4
|
+
export { useModalHandler } from './src/hooks/modal-handler'
|
|
5
|
+
export { ComponentState, ComponentStateContext } from './src/context/component/component-state'
|
package/package.json
CHANGED
|
@@ -1,47 +1,46 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "dynamic-modal",
|
|
3
|
-
"version": "1.1.
|
|
4
|
-
"description": "The dynamic-modal is a solution of creation different modals into project using a json configuration file",
|
|
5
|
-
"main": "index.js",
|
|
6
|
-
"scripts": {
|
|
7
|
-
"build": "tsc",
|
|
8
|
-
"lint": "eslint .",
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
"
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"
|
|
29
|
-
|
|
30
|
-
"@
|
|
31
|
-
"@types/react": "^19.0.
|
|
32
|
-
"@
|
|
33
|
-
"@typescript-eslint/
|
|
34
|
-
"
|
|
35
|
-
"eslint": "^
|
|
36
|
-
"eslint-plugin-react": "^
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"typescript": "^
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
"react": "^19.0.0",
|
|
44
|
-
"react-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "dynamic-modal",
|
|
3
|
+
"version": "1.1.7",
|
|
4
|
+
"description": "The dynamic-modal is a solution of creation different modals into project using a json configuration file",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"build": "tsc",
|
|
8
|
+
"lint": "eslint .",
|
|
9
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
10
|
+
},
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "git+https://gitlab.com/f.salazar/dynamic-modal.git"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"modal",
|
|
17
|
+
"react",
|
|
18
|
+
"next",
|
|
19
|
+
"dynamic",
|
|
20
|
+
"json"
|
|
21
|
+
],
|
|
22
|
+
"author": "Francisco J. Salazar G",
|
|
23
|
+
"license": "ISC",
|
|
24
|
+
"bugs": {
|
|
25
|
+
"url": "https://gitlab.com/f.salazar/dynamic-modal/issues"
|
|
26
|
+
},
|
|
27
|
+
"homepage": "https://gitlab.com/f.salazar/dynamic-modal#readme",
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@eslint/js": "^9.22.0",
|
|
30
|
+
"@types/react": "^19.0.10",
|
|
31
|
+
"@types/react-dom": "^19.0.4",
|
|
32
|
+
"@typescript-eslint/eslint-plugin": "^8.26.1",
|
|
33
|
+
"@typescript-eslint/parser": "^8.26.1",
|
|
34
|
+
"eslint": "^9.22.0",
|
|
35
|
+
"eslint-plugin-react": "^7.37.4",
|
|
36
|
+
"eslint-plugin-react-hooks": "^5.2.0",
|
|
37
|
+
"globals": "^16.0.0",
|
|
38
|
+
"typescript": "^5.8.2",
|
|
39
|
+
"typescript-eslint": "^8.26.1"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"react": "^19.0.0",
|
|
43
|
+
"react-dom": "^19.0.0",
|
|
44
|
+
"react-hook-form": "^7.54.2"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -1,67 +1,67 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
|
|
3
|
-
import React, { ChangeEvent, FC } from 'react'
|
|
4
|
-
import { IFileResult, IInputUpload } from '../../interfaces/input-upload'
|
|
5
|
-
|
|
6
|
-
const InputUpload: FC<IInputUpload> = ({ onChange, readAsArrayBuffer, ...props }: IInputUpload) => {
|
|
7
|
-
|
|
8
|
-
const onChangeHandler = (event: ChangeEvent<HTMLInputElement>) => {
|
|
9
|
-
if (props.read && event.target.files) {
|
|
10
|
-
readFileBlob(event.target.files[0], false)
|
|
11
|
-
.then((result) => onChange(result))
|
|
12
|
-
.catch((err) => {
|
|
13
|
-
console.error('file read error', err)
|
|
14
|
-
onChange({name:'', size: 0, data: ''})
|
|
15
|
-
})
|
|
16
|
-
} else {
|
|
17
|
-
onChange(event.target.files)
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const readFileBlob = (blob: File, image: boolean): Promise<IFileResult> => {
|
|
22
|
-
return new Promise((resolve, reject) => {
|
|
23
|
-
const fileReader = new FileReader()
|
|
24
|
-
if(image) fileReader.readAsDataURL(blob)
|
|
25
|
-
else if (readAsArrayBuffer) fileReader.readAsArrayBuffer(blob)
|
|
26
|
-
else fileReader.readAsText(blob)
|
|
27
|
-
|
|
28
|
-
fileReader.onload = () => {
|
|
29
|
-
const fileResult: IFileResult = {
|
|
30
|
-
name: blob.name,
|
|
31
|
-
size: blob.size,
|
|
32
|
-
data: fileReader.result as string
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
resolve(fileResult)
|
|
36
|
-
}
|
|
37
|
-
fileReader.onerror = (error) => {
|
|
38
|
-
reject(error)
|
|
39
|
-
}
|
|
40
|
-
})
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return (
|
|
44
|
-
<div className='flex flex-col w-full gap-1 text-center'>
|
|
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>}
|
|
46
|
-
<input
|
|
47
|
-
className="file:transition-all file:delay-150 block w-full text-sm text-slate-500
|
|
48
|
-
file:mr-4 file:py-2 file:px-4 file:rounded-md
|
|
49
|
-
file:border-0 file:text-sm file:font-semibold
|
|
50
|
-
file:bg-gray-100 file:text-blue-600
|
|
51
|
-
hover:file:bg-blue-700 hover:file:text-white cursor-pointer disabled:cursor-not-allowed"
|
|
52
|
-
aria-describedby={`file-input-${props.id}-help`}
|
|
53
|
-
id={`file-input-${props.id}`}
|
|
54
|
-
type="file"
|
|
55
|
-
onChange={onChangeHandler}
|
|
56
|
-
{...props}
|
|
57
|
-
/>
|
|
58
|
-
<p
|
|
59
|
-
className="mt-1 text-sm text-gray-500 dark:text-gray-300 text-start"
|
|
60
|
-
id={`file-input-${props.id}-help`}>
|
|
61
|
-
{props.helpText?.toUpperCase()}
|
|
62
|
-
</p>
|
|
63
|
-
</div>
|
|
64
|
-
)
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export default InputUpload
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import React, { ChangeEvent, FC } from 'react'
|
|
4
|
+
import { IFileResult, IInputUpload } from '../../interfaces/input-upload'
|
|
5
|
+
|
|
6
|
+
const InputUpload: FC<IInputUpload> = ({ onChange, readAsArrayBuffer, ...props }: IInputUpload) => {
|
|
7
|
+
|
|
8
|
+
const onChangeHandler = (event: ChangeEvent<HTMLInputElement>) => {
|
|
9
|
+
if (props.read && event.target.files) {
|
|
10
|
+
readFileBlob(event.target.files[0], false)
|
|
11
|
+
.then((result) => onChange(result))
|
|
12
|
+
.catch((err) => {
|
|
13
|
+
console.error('file read error', err)
|
|
14
|
+
onChange({name:'', size: 0, data: ''})
|
|
15
|
+
})
|
|
16
|
+
} else {
|
|
17
|
+
onChange(event.target.files)
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const readFileBlob = (blob: File, image: boolean): Promise<IFileResult> => {
|
|
22
|
+
return new Promise((resolve, reject) => {
|
|
23
|
+
const fileReader = new FileReader()
|
|
24
|
+
if(image) fileReader.readAsDataURL(blob)
|
|
25
|
+
else if (readAsArrayBuffer) fileReader.readAsArrayBuffer(blob)
|
|
26
|
+
else fileReader.readAsText(blob)
|
|
27
|
+
|
|
28
|
+
fileReader.onload = () => {
|
|
29
|
+
const fileResult: IFileResult = {
|
|
30
|
+
name: blob.name,
|
|
31
|
+
size: blob.size,
|
|
32
|
+
data: fileReader.result as string
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
resolve(fileResult)
|
|
36
|
+
}
|
|
37
|
+
fileReader.onerror = (error) => {
|
|
38
|
+
reject(error)
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<div className='flex flex-col w-full gap-1 text-center'>
|
|
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>}
|
|
46
|
+
<input
|
|
47
|
+
className="file:transition-all file:delay-150 block w-full text-sm text-slate-500
|
|
48
|
+
file:mr-4 file:py-2 file:px-4 file:rounded-md
|
|
49
|
+
file:border-0 file:text-sm file:font-semibold
|
|
50
|
+
file:bg-gray-100 file:text-blue-600
|
|
51
|
+
hover:file:bg-blue-700 hover:file:text-white cursor-pointer disabled:cursor-not-allowed"
|
|
52
|
+
aria-describedby={`file-input-${props.id}-help`}
|
|
53
|
+
id={`file-input-${props.id}`}
|
|
54
|
+
type="file"
|
|
55
|
+
onChange={onChangeHandler}
|
|
56
|
+
{...props}
|
|
57
|
+
/>
|
|
58
|
+
<p
|
|
59
|
+
className="mt-1 text-sm text-gray-500 dark:text-gray-300 text-start"
|
|
60
|
+
id={`file-input-${props.id}-help`}>
|
|
61
|
+
{props.helpText?.toUpperCase()}
|
|
62
|
+
</p>
|
|
63
|
+
</div>
|
|
64
|
+
)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export default InputUpload
|