@@ -11,7 +11,7 @@ import {
11
11
} from '@chakra-ui/react' ;
12
12
import React , { useEffect } from 'react' ;
13
13
import { useFieldArray , useForm } from 'react-hook-form' ;
14
- import { FaPlus , FaTrash } from 'react-icons/fa' ;
14
+ import { FaAngleDoubleRight , FaAngleRight , FaPlus , FaTrash } from 'react-icons/fa' ;
15
15
import { useAppDispatch , useAppSelector } from '../../../app/hooks' ;
16
16
import { pythonIdentifierPattern } from '../../../common/validation' ;
17
17
import { PythonDeclaration } from '../../packageData/model/PythonDeclaration' ;
@@ -45,6 +45,8 @@ export const EnumForm: React.FC<EnumFormProps> = function ({ target }) {
45
45
handleSubmit,
46
46
setFocus,
47
47
reset,
48
+ watch,
49
+ setValue,
48
50
formState : { errors } ,
49
51
} = useForm < EnumFormState > ( {
50
52
defaultValues : {
@@ -63,6 +65,8 @@ export const EnumForm: React.FC<EnumFormProps> = function ({ target }) {
63
65
name : 'pairs' ,
64
66
} ) ;
65
67
68
+ const watchPairs = watch ( 'pairs' ) ;
69
+
66
70
useEffect ( ( ) => {
67
71
try {
68
72
setFocus ( 'enumName' ) ;
@@ -113,6 +117,21 @@ export const EnumForm: React.FC<EnumFormProps> = function ({ target }) {
113
117
dispatch ( hideAnnotationForm ( ) ) ;
114
118
} ;
115
119
120
+ const onGenerate = ( index : number ) => ( ) => {
121
+ generateEnumName ( index ) ;
122
+ } ;
123
+
124
+ const onGenerateAll = ( ) => {
125
+ for ( let i = 0 ; i < watchPairs . length ; i ++ ) {
126
+ generateEnumName ( i ) ;
127
+ }
128
+ } ;
129
+
130
+ const generateEnumName = ( index : number ) => {
131
+ const instanceName = formatEnumName ( watchPairs [ index ] . stringValue . toUpperCase ( ) ) ;
132
+ setValue ( `pairs.${ index } .instanceName` , instanceName ) ;
133
+ } ;
134
+
116
135
// Rendering -------------------------------------------------------------------------------------------------------
117
136
118
137
return (
@@ -141,6 +160,12 @@ export const EnumForm: React.FC<EnumFormProps> = function ({ target }) {
141
160
< Text fontSize = "md" fontWeight = "medium" w = "100%" >
142
161
String value:
143
162
</ Text >
163
+ < IconButton
164
+ icon = { < FaAngleDoubleRight /> }
165
+ aria-label = "Generate all instance names"
166
+ colorScheme = "blue"
167
+ onClick = { onGenerateAll }
168
+ />
144
169
< Text fontSize = "md" fontWeight = "medium" w = "100%" >
145
170
Instance name:
146
171
</ Text >
@@ -154,12 +179,27 @@ export const EnumForm: React.FC<EnumFormProps> = function ({ target }) {
154
179
{ ...register ( `pairs.${ index } .stringValue` , {
155
180
required : 'This is required.' ,
156
181
} ) }
182
+ onBlur = { ( ) => {
183
+ if (
184
+ watchPairs [ index ] . stringValue . length !== 0 &&
185
+ watchPairs [ index ] . instanceName . length === 0
186
+ ) {
187
+ generateEnumName ( index ) ;
188
+ }
189
+ } }
157
190
/>
158
191
< FormErrorMessage >
159
192
< FormErrorIcon /> { errors ?. pairs ?. [ index ] ?. stringValue ?. message }
160
193
</ FormErrorMessage >
161
194
</ FormControl >
162
195
196
+ < IconButton
197
+ icon = { < FaAngleRight /> }
198
+ aria-label = "Generate instance name"
199
+ colorScheme = "blue"
200
+ onClick = { onGenerate ( index ) }
201
+ />
202
+
163
203
< FormControl isInvalid = { Boolean ( errors ?. pairs ?. [ index ] ?. instanceName ) } >
164
204
< Input
165
205
{ ...register ( `pairs.${ index } .instanceName` , {
@@ -189,3 +229,16 @@ export const EnumForm: React.FC<EnumFormProps> = function ({ target }) {
189
229
</ AnnotationForm >
190
230
) ;
191
231
} ;
232
+
233
+ const formatEnumName = ( stringValue : string ) => {
234
+ const segments = stringValue . split ( / [ _ \- . ] / u) ;
235
+ const formattedString = segments
236
+ . map ( ( segment ) => segment . replaceAll ( / \W / gu, '' ) . toUpperCase ( ) )
237
+ . filter ( ( segment ) => segment . length > 0 )
238
+ . join ( '_' ) ;
239
+
240
+ if ( formattedString . length === 0 || formattedString . charAt ( 0 ) . match ( / \d / u) ) {
241
+ return '_' + formattedString ;
242
+ }
243
+ return formattedString ;
244
+ } ;
0 commit comments