11import React from 'react' ;
22
3- import { Plus } from '@gravity-ui/icons' ;
4- import { Button , Icon , Label } from '@gravity-ui/uikit' ;
3+ import { Plus , TrashBin } from '@gravity-ui/icons' ;
4+ import { Button , Icon , Label , Popover } from '@gravity-ui/uikit' ;
55import set from 'lodash/set' ;
66
77import {
@@ -21,6 +21,7 @@ import {
2121 transformArrIn ,
2222} from '../../../../core' ;
2323import { block } from '../../../utils' ;
24+ import i18n from '../../../i18n' ;
2425
2526import './ArrayBase.scss' ;
2627
@@ -42,9 +43,19 @@ export const ArrayBase: ArrayInput = ({spec, name, arrayInput, input}) => {
4243 return isBooleanSpec ( spec . items ) || isNumberSpec ( spec . items ) || isStringSpec ( spec . items ) ;
4344 } , [ spec . items ] ) ;
4445
45- const disabledRemoveButton = React . useMemo ( ( ) => {
46- return keys . length <= spec . minLength ;
47- } , [ keys . length , spec . minLength ] ) ;
46+ const disabledButtonLength = React . useMemo ( ( ) => {
47+ if ( spec . viewSpec . enableLockLength ) {
48+ return {
49+ remove : keys . length <= ( spec . minLength || 0 ) ,
50+ add : keys . length >= ( spec . maxLength || Infinity ) ,
51+ } ;
52+ }
53+
54+ return {
55+ remove : false ,
56+ add : false ,
57+ } ;
58+ } , [ keys . length , spec . maxLength , spec . minLength , spec . viewSpec . enableLockLength ] ) ;
4859
4960 const getItemSpec = React . useCallback (
5061 ( idx : number ) : typeof spec . items | null => {
@@ -76,6 +87,13 @@ export const ArrayBase: ArrayInput = ({spec, name, arrayInput, input}) => {
7687 [ input . onChange , input . name ] ,
7788 ) ;
7889
90+ const removeItem = React . useCallback (
91+ ( key : string ) => {
92+ arrayInput . onItemRemove ( key ) ;
93+ } ,
94+ [ arrayInput ] ,
95+ ) ;
96+
7997 const AddButton : React . FC = React . useCallback ( ( ) => {
8098 let onClick = ( ) => arrayInput . onItemAdd ( undefined ) ;
8199
@@ -91,20 +109,25 @@ export const ArrayBase: ArrayInput = ({spec, name, arrayInput, input}) => {
91109 title = spec . viewSpec . layoutTitle ;
92110 }
93111
94- if ( keys . length >= spec . maxLength ) {
95- return null ;
96- }
97-
98112 return (
99- < Button
100- onClick = { onClick }
101- disabled = { spec . viewSpec . disabled }
102- qa = { qa }
103- className = { b ( 'add-button' , { right : spec . viewSpec . addButtonPosition === 'right' } ) }
113+ < Popover
114+ content = { i18n ( 'label_error-max-length-array' , {
115+ count : spec . maxLength ,
116+ } ) }
117+ disabled = { ! disabledButtonLength . add }
104118 >
105- < Icon data = { Plus } size = { 14 } />
106- { title || null }
107- </ Button >
119+ < Button
120+ onClick = { onClick }
121+ disabled = { spec . viewSpec . disabled || disabledButtonLength . add }
122+ qa = { qa }
123+ className = { b ( 'add-button' , {
124+ right : spec . viewSpec . addButtonPosition === 'right' ,
125+ } ) }
126+ >
127+ < Icon data = { Plus } size = { 14 } />
128+ { title || null }
129+ </ Button >
130+ </ Popover >
108131 ) ;
109132 } , [
110133 arrayInput ,
@@ -115,7 +138,7 @@ export const ArrayBase: ArrayInput = ({spec, name, arrayInput, input}) => {
115138 spec . viewSpec . itemLabel ,
116139 spec . viewSpec . layoutTitle ,
117140 spec . viewSpec . addButtonPosition ,
118- keys ,
141+ disabledButtonLength ,
119142 ] ) ;
120143
121144 const items = React . useMemo (
@@ -142,6 +165,25 @@ export const ArrayBase: ArrayInput = ({spec, name, arrayInput, input}) => {
142165 parentOnUnmount = { input . parentOnUnmount }
143166 spec = { itemSpec }
144167 name = { `${ name } .<${ key } >` }
168+ additionalContentLayout = {
169+ < Popover
170+ content = { i18n ( 'label_error-min-length-array' , {
171+ count : spec . minLength ,
172+ } ) }
173+ disabled = { ! disabledButtonLength . remove }
174+ >
175+ < Button
176+ view = "flat-secondary"
177+ onClick = { ( ) => removeItem ( key ) }
178+ key = { `remove-${ key } ` }
179+ qa = { `${ name } -item-remove-${ key } ` }
180+ disabled = { disabledButtonLength . remove }
181+ className = { b ( 'remove-button' ) }
182+ >
183+ < Icon data = { TrashBin } size = { 16 } />
184+ </ Button >
185+ </ Popover >
186+ }
145187 />
146188 </ React . Fragment >
147189 ) ;
@@ -154,6 +196,9 @@ export const ArrayBase: ArrayInput = ({spec, name, arrayInput, input}) => {
154196 input . parentOnUnmount ,
155197 input . value ,
156198 spec . viewSpec . itemPrefix ,
199+ spec . minLength ,
200+ disabledButtonLength . remove ,
201+ removeItem ,
157202 ] ,
158203 ) ;
159204
@@ -168,7 +213,6 @@ export const ArrayBase: ArrayInput = ({spec, name, arrayInput, input}) => {
168213 'add-button-down' :
169214 spec . viewSpec . addButtonPosition !== 'right' && keys . length > 0 ,
170215 'items-primitive' : itemsPrimitive ,
171- 'disabled-remove-button' : disabledRemoveButton ,
172216 } ) }
173217 >
174218 { items }
0 commit comments