11import React from 'react' ;
22
33import { Plus } from '@gravity-ui/icons' ;
4- import { Button , Icon } from '@gravity-ui/uikit' ;
4+ import { Button , Icon , Label } from '@gravity-ui/uikit' ;
55import _ from 'lodash' ;
66
77import {
@@ -19,6 +19,11 @@ import {
1919 isObjectSpec ,
2020 transformArrIn ,
2121} from '../../../../core' ;
22+ import { block } from '../../../utils' ;
23+
24+ import './ArrayBase.scss' ;
25+
26+ const b = block ( 'array-base' ) ;
2227
2328export const ArrayBase : ArrayInput = ( { spec, name, arrayInput, input} ) => {
2429 const keys = React . useMemo (
@@ -32,20 +37,6 @@ export const ArrayBase: ArrayInput = ({spec, name, arrayInput, input}) => {
3237
3338 const itemSpecCorrect = React . useMemo ( ( ) => isCorrectSpec ( spec . items ) , [ spec . items ] ) ;
3439
35- const onItemAdd = React . useCallback ( ( ) => {
36- let item ;
37-
38- if ( ! spec . items ?. required ) {
39- if ( isArraySpec ( spec . items ) ) {
40- item = { [ OBJECT_ARRAY_FLAG ] : true , [ OBJECT_ARRAY_CNT ] : 0 } ;
41- } else if ( isObjectSpec ( spec . items ) ) {
42- item = { } ;
43- }
44- }
45-
46- arrayInput . onItemAdd ( item ) ;
47- } , [ arrayInput . onItemAdd , spec . items ] ) ;
48-
4940 const getItemSpec = React . useCallback (
5041 ( idx : number ) : typeof spec . items | null => {
5142 if ( ! itemSpecCorrect ) {
@@ -80,6 +71,55 @@ export const ArrayBase: ArrayInput = ({spec, name, arrayInput, input}) => {
8071 [ input . onChange , input . name ] ,
8172 ) ;
8273
74+ const AddButton : React . FC = React . useCallback ( ( ) => {
75+ let onClick = ( ) => {
76+ let item ;
77+
78+ if ( ! spec . items ?. required ) {
79+ if ( isArraySpec ( spec . items ) ) {
80+ item = { [ OBJECT_ARRAY_FLAG ] : true , [ OBJECT_ARRAY_CNT ] : 0 } ;
81+ } else if ( isObjectSpec ( spec . items ) ) {
82+ item = { } ;
83+ }
84+ }
85+
86+ arrayInput . onItemAdd ( item ) ;
87+ } ;
88+
89+ let qa = `${ name } -add-item` ;
90+ let title = spec . viewSpec . itemLabel ;
91+
92+ if ( ! arrayInput . value && spec . defaultValue ) {
93+ onClick = ( ) => {
94+ input . onChange ( transformArrIn < ArrayValue , FieldArrayValue > ( spec . defaultValue ! ) ) ;
95+ } ;
96+
97+ qa = `${ name } -init-arr` ;
98+ title = spec . viewSpec . layoutTitle ;
99+ }
100+
101+ return (
102+ < Button
103+ onClick = { onClick }
104+ disabled = { spec . viewSpec . disabled }
105+ qa = { qa }
106+ className = { b ( 'add-button' , { right : spec . viewSpec . addButtonPosition === 'right' } ) }
107+ >
108+ < Icon data = { Plus } size = { 14 } />
109+ { title || null }
110+ </ Button >
111+ ) ;
112+ } , [
113+ arrayInput ,
114+ input ,
115+ name ,
116+ spec . defaultValue ,
117+ spec . items ,
118+ spec . viewSpec . disabled ,
119+ spec . viewSpec . itemLabel ,
120+ spec . viewSpec . layoutTitle ,
121+ ] ) ;
122+
83123 const items = React . useMemo (
84124 ( ) =>
85125 keys . map ( ( key , idx ) => {
@@ -89,50 +129,51 @@ export const ArrayBase: ArrayInput = ({spec, name, arrayInput, input}) => {
89129 return null ;
90130 }
91131
132+ const showItemPrefix = idx !== 0 && spec . viewSpec . itemPrefix ;
133+
92134 return (
93- < Controller
94- value = { input . value ?. [ `<${ key } >` ] }
95- parentOnChange = { parentOnChange }
96- parentOnUnmount = { input . parentOnUnmount }
97- spec = { itemSpec }
98- name = { `${ name } .<${ key } >` }
99- key = { `${ name } .<${ key } >` }
100- />
135+ < React . Fragment key = { `${ name } .<${ key } >` } >
136+ { showItemPrefix ? (
137+ < Label size = "m" className = { b ( 'item-prefix' ) } >
138+ { spec . viewSpec . itemPrefix }
139+ </ Label >
140+ ) : null }
141+ < Controller
142+ value = { input . value ?. [ `<${ key } >` ] }
143+ parentOnChange = { parentOnChange }
144+ parentOnUnmount = { input . parentOnUnmount }
145+ spec = { itemSpec }
146+ name = { `${ name } .<${ key } >` }
147+ />
148+ </ React . Fragment >
101149 ) ;
102150 } ) ,
103- [ keys . join ( '' ) , name , getItemSpec , parentOnChange , input . parentOnUnmount , input . value ] ,
151+ [
152+ keys . join ( '' ) ,
153+ name ,
154+ getItemSpec ,
155+ parentOnChange ,
156+ input . parentOnUnmount ,
157+ input . value ,
158+ spec . viewSpec . itemPrefix ,
159+ ] ,
104160 ) ;
105161
106162 if ( ! itemSpecCorrect ) {
107163 return null ;
108164 }
109165
110166 return (
111- < React . Fragment >
112- { items }
113- { ! arrayInput . value && spec . defaultValue ? (
114- < Button
115- onClick = { ( ) =>
116- input . onChange (
117- transformArrIn < ArrayValue , FieldArrayValue > ( spec . defaultValue ! ) ,
118- )
119- }
120- disabled = { spec . viewSpec . disabled }
121- qa = { `${ name } -init-arr` }
122- >
123- < Icon data = { Plus } size = { 14 } />
124- { spec . viewSpec . layoutTitle || null }
125- </ Button >
126- ) : (
127- < Button
128- onClick = { onItemAdd }
129- disabled = { spec . viewSpec . disabled }
130- qa = { `${ name } -add-item` }
131- >
132- < Icon data = { Plus } size = { 14 } />
133- { spec . viewSpec . itemLabel || null }
134- </ Button >
135- ) }
136- </ React . Fragment >
167+ < div className = { b ( { 'add-button-right' : spec . viewSpec . addButtonPosition === 'right' } ) } >
168+ < div
169+ className = { b ( 'items-wrapper' , {
170+ 'add-button-down' :
171+ spec . viewSpec . addButtonPosition !== 'right' && keys . length > 0 ,
172+ } ) }
173+ >
174+ { items }
175+ </ div >
176+ < AddButton />
177+ </ div >
137178 ) ;
138179} ;
0 commit comments