1
- import { createElement , createRef , Fragment , ReactElement , RefObject , useEffect , useRef } from 'react'
1
+ import { createElement , createRef , Fragment , ReactElement , RefObject , useEffect , useRef , useState } from 'react'
2
2
// eslint-disable-next-line import/no-extraneous-dependencies
3
3
import { followCursor } from 'tippy.js'
4
4
@@ -9,10 +9,10 @@ import { ResizableTagTextArea } from '@Common/CustomTagSelector'
9
9
import { ComponentSizeType } from '@Shared/constants'
10
10
11
11
import { Button , ButtonStyleType , ButtonVariantType } from '../Button'
12
- import { SelectTextArea } from '../SelectTextArea'
13
12
import {
14
13
getSelectPickerOptionByValue ,
15
14
SelectPicker ,
15
+ SelectPickerTextArea ,
16
16
SelectPickerOptionType ,
17
17
SelectPickerVariantType ,
18
18
} from '../SelectPicker'
@@ -46,6 +46,7 @@ export const DynamicDataTableRow = <K extends string, CustomStateType = Record<s
46
46
leadingCellIcon,
47
47
trailingCellIcon,
48
48
buttonCellWrapComponent,
49
+ focusableFieldKey,
49
50
} : DynamicDataTableRowProps < K , CustomStateType > ) => {
50
51
// CONSTANTS
51
52
const isFirstRowEmpty = headers . every ( ( { key } ) => ! rows [ 0 ] ?. data [ key ] . value )
@@ -59,6 +60,10 @@ export const DynamicDataTableRow = <K extends string, CustomStateType = Record<s
59
60
isDeletionNotAllowed || readOnly ,
60
61
)
61
62
63
+ // STATES
64
+ const [ isRowAdded , setIsRowAdded ] = useState ( false )
65
+
66
+ // CELL REFS
62
67
const cellRef = useRef < Record < string | number , Record < K , RefObject < HTMLTextAreaElement > > > > ( )
63
68
if ( ! cellRef . current ) {
64
69
cellRef . current = rows . reduce (
@@ -71,6 +76,7 @@ export const DynamicDataTableRow = <K extends string, CustomStateType = Record<s
71
76
}
72
77
73
78
useEffect ( ( ) => {
79
+ setIsRowAdded ( rows . length && Object . keys ( cellRef . current ) . length < rows . length )
74
80
const rowIds = rows . map ( ( { id } ) => id )
75
81
76
82
const updatedCellRef = rowIds . reduce ( ( acc , curr ) => {
@@ -85,6 +91,15 @@ export const DynamicDataTableRow = <K extends string, CustomStateType = Record<s
85
91
cellRef . current = updatedCellRef
86
92
} , [ rows . length ] )
87
93
94
+ useEffect ( ( ) => {
95
+ // Using the below logic to ensure the cell is focused after row addition.
96
+ const cell = cellRef . current [ rows [ 0 ] . id ] [ focusableFieldKey || headers [ 0 ] . key ] . current
97
+ if ( isRowAdded && cell ) {
98
+ cell . focus ( )
99
+ setIsRowAdded ( false )
100
+ }
101
+ } , [ isRowAdded ] )
102
+
88
103
// METHODS
89
104
const onChange =
90
105
( row : DynamicDataTableRowType < K , CustomStateType > , key : K ) =>
@@ -94,7 +109,7 @@ export const DynamicDataTableRow = <K extends string, CustomStateType = Record<s
94
109
switch ( row . data [ key ] . type ) {
95
110
case DynamicDataTableRowDataType . DROPDOWN :
96
111
case DynamicDataTableRowDataType . SELECT_TEXT :
97
- value = ( e as SelectPickerOptionType < string > ) . value
112
+ value = ( e as SelectPickerOptionType < string > ) ? .value || ''
98
113
extraData . selectedValue = e
99
114
break
100
115
case DynamicDataTableRowDataType . FILE_UPLOAD :
@@ -138,31 +153,32 @@ export const DynamicDataTableRow = <K extends string, CustomStateType = Record<s
138
153
/>
139
154
</ div >
140
155
)
141
- case DynamicDataTableRowDataType . SELECT_TEXT :
156
+ case DynamicDataTableRowDataType . SELECT_TEXT : {
157
+ const { value, props } = row . data [ key ]
158
+ const { isCreatable = true } = props
159
+
142
160
return (
143
- < div className = "dynamic-data-table__select-text-area w-100 h-100 flex top dc__align-self-start" >
144
- < SelectTextArea
145
- { ...row . data [ key ] . props }
146
- value = { row . data [ key ] . value }
147
- onChange = { onChange ( row , key ) }
161
+ < div className = "w-100 h-100 flex top dc__align-self-start" >
162
+ < SelectPickerTextArea
163
+ isCreatable = { isCreatable }
164
+ isClearable
165
+ { ...props }
166
+ variant = { SelectPickerVariantType . BORDER_LESS }
167
+ classNamePrefix = "dynamic-data-table__cell__select-picker"
148
168
inputId = { `data-table-${ row . id } -${ key } -cell` }
149
- disabled = { isDisabled }
150
- refVar = { cellRef ?. current ?. [ row . id ] ?. [ key ] }
151
- dependentRefs = { cellRef ?. current ?. [ row . id ] }
152
- selectPickerProps = { {
153
- ...row . data [ key ] . props ?. selectPickerProps ,
154
- classNamePrefix : 'dynamic-data-table__cell__select-picker' ,
155
- } }
156
- textAreaProps = { {
157
- ...row . data [ key ] . props ?. textAreaProps ,
158
- className : 'dynamic-data-table__cell-input placeholder-cn5 py-8 pr-32 cn-9 fs-13 lh-20' ,
159
- disableOnBlurResizeToMinHeight : true ,
160
- minHeight : 20 ,
161
- maxHeight : 160 ,
162
- } }
169
+ value = { getSelectPickerOptionByValue (
170
+ props ?. options ,
171
+ value ,
172
+ isCreatable && value ? { label : value , value } : null ,
173
+ ) }
174
+ onChange = { onChange ( row , key ) }
175
+ isDisabled = { isDisabled }
176
+ formatCreateLabel = { ( input ) => `Use ${ input } ` }
177
+ fullWidth
163
178
/>
164
179
</ div >
165
180
)
181
+ }
166
182
case DynamicDataTableRowDataType . BUTTON :
167
183
return (
168
184
< div className = "w-100 h-100 flex top" >
@@ -240,12 +256,17 @@ export const DynamicDataTableRow = <K extends string, CustomStateType = Record<s
240
256
? cellError [ row . id ] [ key ]
241
257
: { isValid : true , errorMessages : [ ] }
242
258
259
+ const isSelectText = row . data [ key ] . type === DynamicDataTableRowDataType . SELECT_TEXT
260
+
243
261
if ( isValid ) {
244
262
return null
245
263
}
246
264
265
+ // Adding 'no-error' class to hide error when SelectPickerTextArea is focused.
247
266
return (
248
- < div className = "dynamic-data-table__error bcn-0 dc__border br-4 py-7 px-8 flexbox-col dc__gap-4" >
267
+ < div
268
+ className = { `dynamic-data-table__error bcn-0 dc__border br-4 py-7 px-8 flexbox-col dc__gap-4 ${ isSelectText ? 'no-error' : '' } ` }
269
+ >
249
270
{ errorMessages . map ( ( error ) => renderErrorMessage ( error ) ) }
250
271
</ div >
251
272
)
@@ -264,7 +285,7 @@ export const DynamicDataTableRow = <K extends string, CustomStateType = Record<s
264
285
plugins = { [ followCursor ] }
265
286
>
266
287
< div
267
- className = { `dynamic-data-table__cell bcn-0 flexbox dc__align-items-center dc__gap-4 dc__position-rel ${ isDisabled ? 'cursor-not-allowed no-hover' : '' } ${ ! isDisabled && hasError ? 'dynamic-data-table__cell--error no-hover' : '' } ${ ! rowTypeHasInputField ( row . data [ key ] . type ) ? 'no-hover no-focus' : '' } ` }
288
+ className = { `dynamic-data-table__cell bcn-0 flexbox dc__align-items-center dc__gap-4 dc__position-rel ${ isDisabled ? 'dc__disabled no-hover' : '' } ${ ! isDisabled && hasError ? 'dynamic-data-table__cell--error no-hover' : '' } ${ ! rowTypeHasInputField ( row . data [ key ] . type ) ? 'no-hover no-focus' : '' } ` }
268
289
>
269
290
{ renderCellIcon ( row , key , true ) }
270
291
{ renderCellContent ( row , key ) }
0 commit comments