@@ -7,120 +7,118 @@ import { Help } from './Help'
7
7
import { Flavor , ChartProperty } from '../../types'
8
8
import { ArrayControlConfig } from './types'
9
9
10
- interface ArrayControlProps {
10
+ interface ArrayControlProps < Item > {
11
11
id : string
12
12
property : ChartProperty
13
- value : unknown [ ]
13
+ value : Item [ ]
14
14
flavors : Flavor [ ]
15
15
currentFlavor : Flavor
16
- config : ArrayControlConfig
17
- onChange : ( value : unknown ) => void
16
+ config : ArrayControlConfig < Item >
17
+ onChange : ( value : Item [ ] ) => void
18
18
context ?: any
19
19
}
20
20
21
- export const ArrayControl = memo (
22
- ( {
23
- property,
24
- flavors,
25
- currentFlavor,
26
- value,
27
- onChange,
28
- config : {
29
- props,
30
- shouldCreate = false ,
31
- addLabel = 'add' ,
32
- shouldRemove = false ,
33
- removeLabel = 'remove' ,
34
- defaults = { } ,
35
- getItemTitle,
21
+ function NonMemoizedArrayControl < Item = object > ( {
22
+ property,
23
+ flavors,
24
+ currentFlavor,
25
+ value,
26
+ onChange,
27
+ config : {
28
+ props,
29
+ shouldCreate = false ,
30
+ addLabel = 'add' ,
31
+ shouldRemove = false ,
32
+ removeLabel = 'remove' ,
33
+ defaults = { } as Item ,
34
+ getItemTitle,
35
+ } ,
36
+ } : ArrayControlProps < Item > ) {
37
+ const [ activeItems , setActiveItems ] = useState ( [ 0 ] )
38
+ const append = useCallback ( ( ) => {
39
+ onChange ( [ ...value , { ...defaults } ] )
40
+ setActiveItems ( [ value . length ] )
41
+ } , [ value , onChange , defaults , setActiveItems ] )
42
+
43
+ const remove = useCallback (
44
+ ( index : number ) => ( event : MouseEvent ) => {
45
+ event . stopPropagation ( )
46
+ const items = value . filter ( ( _item : any , i ) => i !== index )
47
+ setActiveItems ( [ ] )
48
+ onChange ( items )
36
49
} ,
37
- } : ArrayControlProps ) => {
38
- const [ activeItems , setActiveItems ] = useState ( [ 0 ] )
39
- const append = useCallback ( ( ) => {
40
- onChange ( [ ...value , { ...defaults } ] )
41
- setActiveItems ( [ value . length ] )
42
- } , [ value , onChange , defaults , setActiveItems ] )
43
-
44
- const remove = useCallback (
45
- ( index : number ) => ( event : MouseEvent ) => {
46
- event . stopPropagation ( )
47
- const items = value . filter ( ( _item : any , i ) => i !== index )
48
- setActiveItems ( [ ] )
49
- onChange ( items )
50
- } ,
51
- [ value , onChange , setActiveItems ]
52
- )
53
- const change = useCallback (
54
- ( index : number ) => ( itemValue : unknown ) => {
55
- onChange (
56
- value . map ( ( v , i ) => {
57
- if ( i === index ) return itemValue
58
- return v
59
- } )
60
- )
61
- } ,
62
- [ value , onChange ]
63
- )
64
- const toggle = useCallback (
65
- ( index : number ) => ( ) => {
66
- setActiveItems ( items => {
67
- if ( items . includes ( index ) ) {
68
- return items . filter ( i => i !== index )
69
- }
70
- return [ ...activeItems , index ]
50
+ [ value , onChange , setActiveItems ]
51
+ )
52
+ const change = useCallback (
53
+ ( index : number ) => ( itemValue : Item ) => {
54
+ onChange (
55
+ value . map ( ( v , i ) => {
56
+ if ( i === index ) return itemValue
57
+ return v
71
58
} )
72
- } ,
73
- [ setActiveItems ]
74
- )
75
-
76
- const subProps = useMemo (
77
- ( ) =>
78
- props . map ( prop => ( {
79
- ...prop ,
80
- name : prop . key ,
81
- group : property . group ,
82
- } ) ) ,
83
- [ props ]
84
- )
85
-
86
- return (
87
- < >
88
- < Header >
89
- < PropertyHeader { ...property } />
90
- < Help > { property . help } </ Help >
91
- { shouldCreate && < AddButton onClick = { append } > { addLabel } </ AddButton > }
92
- </ Header >
93
- { value . map ( ( item , index ) => (
94
- < Fragment key = { index } >
95
- < SubHeader isOpened = { activeItems . includes ( index ) } onClick = { toggle ( index ) } >
96
- < Title >
97
- { getItemTitle !== undefined
98
- ? getItemTitle ( index , item )
99
- : `${ property . key } [${ index } ]` }
100
- { shouldRemove && (
101
- < RemoveButton onClick = { remove ( index ) } >
102
- { removeLabel }
103
- </ RemoveButton >
104
- ) }
105
- </ Title >
106
- < Toggle isOpened = { activeItems . includes ( index ) } />
107
- </ SubHeader >
108
- { activeItems . includes ( index ) && (
109
- < ControlsGroup
110
- name = { property . key }
111
- flavors = { flavors }
112
- currentFlavor = { currentFlavor }
113
- controls = { subProps }
114
- settings = { item }
115
- onChange = { change ( index ) }
116
- />
117
- ) }
118
- </ Fragment >
119
- ) ) }
120
- </ >
121
- )
122
- }
123
- )
59
+ )
60
+ } ,
61
+ [ value , onChange ]
62
+ )
63
+ const toggle = useCallback (
64
+ ( index : number ) => ( ) => {
65
+ setActiveItems ( items => {
66
+ if ( items . includes ( index ) ) {
67
+ return items . filter ( i => i !== index )
68
+ }
69
+ return [ ...activeItems , index ]
70
+ } )
71
+ } ,
72
+ [ setActiveItems ]
73
+ )
74
+
75
+ const subProps = useMemo (
76
+ ( ) =>
77
+ props . map ( prop => ( {
78
+ ...prop ,
79
+ name : prop . key ,
80
+ group : property . group ,
81
+ } ) ) ,
82
+ [ props ]
83
+ )
84
+
85
+ return (
86
+ < >
87
+ < Header >
88
+ < PropertyHeader { ...property } />
89
+ < Help > { property . help } </ Help >
90
+ { shouldCreate && < AddButton onClick = { append } > { addLabel } </ AddButton > }
91
+ </ Header >
92
+ { value . map ( ( item , index ) => (
93
+ < Fragment key = { index } >
94
+ < SubHeader isOpened = { activeItems . includes ( index ) } onClick = { toggle ( index ) } >
95
+ < Title >
96
+ { getItemTitle !== undefined
97
+ ? getItemTitle ( index , item )
98
+ : `${ property . key } [${ index } ]` }
99
+ { shouldRemove && (
100
+ < RemoveButton onClick = { remove ( index ) } > { removeLabel } </ RemoveButton >
101
+ ) }
102
+ </ Title >
103
+ < Toggle isOpened = { activeItems . includes ( index ) } />
104
+ </ SubHeader >
105
+ { activeItems . includes ( index ) && (
106
+ < ControlsGroup
107
+ name = { property . key }
108
+ flavors = { flavors }
109
+ currentFlavor = { currentFlavor }
110
+ controls = { subProps }
111
+ settings = { item }
112
+ onChange = { change ( index ) }
113
+ />
114
+ ) }
115
+ </ Fragment >
116
+ ) ) }
117
+ </ >
118
+ )
119
+ }
120
+
121
+ export const ArrayControl = memo ( NonMemoizedArrayControl ) as typeof NonMemoizedArrayControl
124
122
125
123
const Header = styled ( Cell ) `
126
124
border-bottom: 1px solid ${ ( { theme } ) => theme . colors . borderLight } ;
0 commit comments