@@ -16,7 +16,7 @@ const ALL_TYPES = [...PRIMITIVE_TYPES, 'Object', 'Array', 'Ref'];
1616const ARRAY_ITEM_TYPES = [ ...PRIMITIVE_TYPES , 'Object' , 'Ref' ] ;
1717
1818function createEmptyField ( ) {
19- return { _id : nextFieldId ( ) , key : '' , type : 'String' , required : false } ;
19+ return { _id : nextFieldId ( ) , key : '' , type : 'String' , required : false , unique : false } ;
2020}
2121
2222// FUNCTION - FIELD ROW COMPONENT
@@ -34,10 +34,13 @@ function FieldRow({ field, index, depth, collections, onChange, onRemove }) {
3434 delete updated . ref ;
3535 if ( value === 'Object' ) {
3636 updated . fields = [ createEmptyField ( ) ] ;
37+ updated . unique = false ;
3738 } else if ( value === 'Array' ) {
3839 updated . items = { type : 'String' } ;
40+ updated . unique = false ;
3941 } else if ( value === 'Ref' ) {
4042 updated . ref = '' ;
43+ updated . unique = false ;
4144 }
4245 }
4346 onChange ( index , updated ) ;
@@ -153,20 +156,43 @@ function FieldRow({ field, index, depth, collections, onChange, onRemove }) {
153156 ) ) }
154157 </ select >
155158
156- { /* Required checkbox */ }
157- < input
158- type = "checkbox"
159- checked = { field . required }
160- disabled = { field . locked }
161- onChange = { ( e ) => handleChange ( 'required' , e . target . checked ) }
162- style = { {
163- accentColor : 'var(--color-primary)' ,
164- transform : 'scale(1.1)' , cursor : field . locked ? 'not-allowed' : 'pointer' , flexShrink : 0 ,
165- opacity : field . locked ? 0.6 : 1
166- } }
167- />
159+ { /* Required Checkbox */ }
160+ < div style = { { width : '24px' , flexShrink : 0 , display : 'flex' , justifyContent : 'center' } } >
161+ < input
162+ type = "checkbox"
163+ aria-label = "required"
164+ checked = { field . required }
165+ disabled = { field . locked }
166+ onChange = { ( e ) => handleChange ( 'required' , e . target . checked ) }
167+ style = { {
168+ accentColor : 'var(--color-primary)' ,
169+ transform : 'scale(1.1)' , cursor : field . locked ? 'not-allowed' : 'pointer' ,
170+ opacity : field . locked ? 0.6 : 1
171+ } }
172+ />
173+ </ div >
174+
175+ { /* Unique Checkbox */ }
176+ < div style = { { width : '24px' , flexShrink : 0 , display : 'flex' , justifyContent : 'center' } } >
177+ { depth === 1 && PRIMITIVE_TYPES . includes ( field . type ) ? (
178+ < input
179+ type = "checkbox"
180+ aria-label = "unique"
181+ checked = { ! ! field . unique }
182+ disabled = { field . locked }
183+ onChange = { ( e ) => handleChange ( 'unique' , e . target . checked ) }
184+ style = { {
185+ accentColor : 'var(--color-primary)' ,
186+ transform : 'scale(1.1)' , cursor : field . locked ? 'not-allowed' : 'pointer' ,
187+ opacity : field . locked ? 0.6 : 1
188+ } }
189+ />
190+ ) : (
191+ < div aria-hidden = "true" />
192+ ) }
193+ </ div >
168194
169- { /* Delete button */ }
195+ { /* Delete Button */ }
170196 < button
171197 type = "button"
172198 onClick = { ( ) => onRemove ( index ) }
@@ -184,7 +210,7 @@ function FieldRow({ field, index, depth, collections, onChange, onRemove }) {
184210 </ button >
185211 </ div >
186212
187- { /* Ref — collection picker */ }
213+ { /* Ref — Collection Picker */ }
188214 { field . type === 'Ref' && (
189215 < div style = { { marginLeft : '26px' , marginBottom : '8px' , display : 'flex' , gap : '8px' , alignItems : 'center' } } >
190216 < span style = { { fontSize : '0.8rem' , color : 'var(--color-text-muted)' , whiteSpace : 'nowrap' } } >
@@ -481,6 +507,7 @@ function CreateCollection() {
481507 < span style = { { flex : 2 } } > NAME</ span >
482508 < span style = { { flex : 1 } } > TYPE</ span >
483509 < span style = { { width : '24px' , textAlign : 'center' } } > REQ</ span >
510+ < span style = { { width : '24px' , textAlign : 'center' } } > UNIQ</ span >
484511 < span style = { { width : '30px' } } > </ span >
485512 </ div >
486513
0 commit comments