1
- import { useMotionValue , motion , Reorder } from 'framer-motion'
1
+ import { useEffect , useState } from 'react'
2
+ import { motion , Reorder } from 'framer-motion'
2
3
3
4
import { cn } from '@/lib/utils'
4
5
import { FormFieldType } from '@/types'
5
6
import { defaultFieldConfig , fieldTypes } from '@/constants'
6
- import { Input } from '@/components/ui/input'
7
7
import { Button } from '@/components/ui/button'
8
8
import {
9
9
DropdownMenu ,
@@ -15,7 +15,7 @@ import {
15
15
} from '@/components/ui/dropdown-menu'
16
16
import If from '@/components/ui/if'
17
17
18
- import { LuGrip , LuColumns , LuPencil , LuTrash2 } from 'react-icons/lu'
18
+ import { LuColumns , LuPencil , LuTrash2 } from 'react-icons/lu'
19
19
20
20
export type FormFieldOrGroup = FormFieldType | FormFieldType [ ]
21
21
@@ -43,6 +43,9 @@ export const FieldItem = ({
43
43
subIndex === ( formFields [ index ] as FormFieldType [ ] ) . length - 1
44
44
45
45
const path = subIndex !== undefined ? [ index , subIndex ] : [ index ]
46
+ const [ columnCount , setColumnCount ] = useState ( ( ) =>
47
+ Array . isArray ( formFields [ index ] ) ? formFields [ index ] . length : 1 ,
48
+ )
46
49
47
50
const addNewColumn = ( variant : string , index : number ) => {
48
51
const newFieldName = `name_${ Math . random ( ) . toString ( ) . slice ( - 10 ) } `
@@ -103,38 +106,43 @@ export const FieldItem = ({
103
106
}
104
107
105
108
const removeColumn = ( ) => {
106
- // Extracting the exact row and subIndex from path
107
109
const rowIndex = path [ 0 ]
108
110
const subIndex = path . length > 1 ? path [ 1 ] : null
109
111
110
112
setFormFields ( ( prevFields ) => {
111
- const newFields = [ ...prevFields ] // Create a shallow copy of formFields
113
+ const newFields = [ ...prevFields ]
112
114
113
115
if ( Array . isArray ( newFields [ rowIndex ] ) ) {
114
- // If it's an array (a row with multiple fields)
115
- const row = [ ...( newFields [ rowIndex ] as FormFieldType [ ] ) ] // Shallow copy of the row
116
+ const row = [ ...( newFields [ rowIndex ] as FormFieldType [ ] ) ]
116
117
117
118
if ( subIndex !== null && subIndex >= 0 && subIndex < row . length ) {
118
- // Only remove the specific field at subIndex
119
119
row . splice ( subIndex , 1 )
120
120
121
- // Update the row after removal
122
121
if ( row . length > 0 ) {
123
- newFields [ rowIndex ] = row // Replace the row with the updated row
122
+ newFields [ rowIndex ] = row
123
+ // Update column count immediately after removal
124
+ setColumnCount ( row . length )
124
125
} else {
125
- // If the row becomes empty, remove the entire row
126
126
newFields . splice ( rowIndex , 1 )
127
+ setColumnCount ( 1 )
127
128
}
128
129
}
129
130
} else {
130
- // If it's a single field, simply remove it
131
131
newFields . splice ( rowIndex , 1 )
132
+ setColumnCount ( 1 )
132
133
}
133
134
134
- return newFields // Update formFields state
135
+ return newFields
135
136
} )
136
137
}
137
138
139
+ useEffect ( ( ) => {
140
+ const newColumnCount = Array . isArray ( formFields [ index ] )
141
+ ? formFields [ index ] . length
142
+ : 1
143
+ setColumnCount ( newColumnCount )
144
+ } , [ formFields , index ] )
145
+
138
146
return (
139
147
< Reorder . Item
140
148
value = { field }
@@ -148,60 +156,33 @@ export const FieldItem = ({
148
156
exit = { { opacity : 0 , y : 20 , transition : { duration : 0.3 } } }
149
157
whileDrag = { { backgroundColor : '#9ca3af' , borderRadius : '12px' } }
150
158
className = { cn ( 'w-full' , {
151
- 'col-span-12' :
152
- Array . isArray ( formFields [ index ] ) && formFields [ index ] . length === 1 ,
153
- 'col-span-6' :
154
- Array . isArray ( formFields [ index ] ) && formFields [ index ] . length === 2 ,
155
- 'col-span-4' :
156
- Array . isArray ( formFields [ index ] ) && formFields [ index ] . length === 3 ,
159
+ 'col-span-12' : columnCount === 1 ,
160
+ 'col-span-6' : columnCount === 2 ,
161
+ 'col-span-4' : columnCount === 3 ,
157
162
} ) }
163
+ key = { `${ field . name } -${ columnCount } ` }
158
164
>
159
- < motion . div layout = "position" className = "flex items-center gap-3" >
165
+ { /* Rest of your component JSX */ }
166
+ < motion . div
167
+ layout = "position"
168
+ className = "flex items-center gap-3"
169
+ key = { `${ field . name } -${ columnCount } ` }
170
+ >
160
171
< div className = "flex items-center gap-1 border rounded-xl px-3 py-1.5 w-full" >
161
172
< If
162
173
condition = { Array . isArray ( formFields [ index ] ) }
163
174
render = { ( ) => < LuColumns className = "cursor-grab w-4 h-4" /> }
164
175
/>
165
176
< div className = "flex items-center w-full" >
166
- < div className = "w-full text-sm" >
167
- { field . variant }
168
- { /* <Input
169
- value={field.label}
170
- onChange={(e) =>
171
- updateFormField(path, { label: e.target.value })
172
- }
173
- placeholder="Enter label"
174
- /> */ }
175
- </ div >
177
+ < div className = "w-full text-sm" > { field . variant } </ div >
176
178
< Button
177
179
variant = "ghost"
178
180
size = "icon"
179
181
onClick = { ( ) => openEditDialog ( field ) }
180
182
>
181
183
< LuPencil />
182
184
</ Button >
183
- < Button
184
- variant = "ghost"
185
- size = "icon"
186
- onClick = { removeColumn }
187
- // onClick={() => {
188
- // setFormFields((prevFields) => {
189
- // const newFields = [...prevFields]
190
- // if (Array.isArray(newFields[index])) {
191
- // // If it's an array, remove the specific subfield
192
- // ;(newFields[index] as FormFieldType[]).splice(subIndex!, 1)
193
- // // If the array becomes empty, remove it entirely
194
- // if ((newFields[index] as FormFieldType[]).length === 0) {
195
- // newFields.splice(index, 1)
196
- // }
197
- // } else {
198
- // // If it's a single field, remove it
199
- // newFields.splice(index, 1)
200
- // }
201
- // return newFields
202
- // })
203
- // }}
204
- >
185
+ < Button variant = "ghost" size = "icon" onClick = { removeColumn } >
205
186
< LuTrash2 />
206
187
</ Button >
207
188
</ div >
@@ -225,7 +206,10 @@ export const FieldItem = ({
225
206
{ fieldTypes . map ( ( fieldType ) => (
226
207
< DropdownMenuItem
227
208
key = { fieldType . name }
228
- onClick = { ( ) => addNewColumn ( fieldType . name , index ) }
209
+ onClick = { ( ) => {
210
+ addNewColumn ( fieldType . name , index )
211
+ setColumnCount ( ( prev ) => prev + 1 )
212
+ } }
229
213
>
230
214
{ fieldType . name }
231
215
</ DropdownMenuItem >
0 commit comments