@@ -8,26 +8,49 @@ const ValueConstraints = ({ attribute, onUpdate }) => {
88 const [ constInput , setConstInput ] = useState ( '' ) ;
99 const [ enumInput , setEnumInput ] = useState ( '' ) ;
1010
11+ // For arrays with simple item types (not $ref), enum/const should be on items, not the array itself
12+ const isSimpleArray = attribute . type === 'array' && attribute . items && ! attribute . items . $ref ;
13+ const effectiveType = isSimpleArray ? attribute . items ?. type : attribute . type ;
14+
15+ // Get enum value from the correct location (items for simple arrays, attribute otherwise)
16+ const currentEnum = isSimpleArray ? attribute . items ?. enum : attribute . enum ;
17+ const currentConst = isSimpleArray ? attribute . items ?. const : attribute . const ;
18+
1119 // Initialize local state from attribute values
1220 useEffect ( ( ) => {
13- setConstInput ( formatValueForInput ( attribute . const ) ) ;
14- } , [ attribute . const ] ) ;
21+ setConstInput ( formatValueForInput ( currentConst ) ) ;
22+ } , [ currentConst ] ) ;
1523
1624 // Initialize enum input as empty (it's only shown when no enum exists yet)
1725 useEffect ( ( ) => {
18- if ( ! attribute . enum || attribute . enum . length === 0 ) {
26+ if ( ! currentEnum || currentEnum . length === 0 ) {
1927 setEnumInput ( '' ) ;
2028 }
21- } , [ attribute . enum ] ) ;
29+ } , [ currentEnum ] ) ;
30+
31+ // Helper to update enum/const at the correct level (items for simple arrays)
32+ const updateValueConstraint = ( updates ) => {
33+ if ( isSimpleArray ) {
34+ // Place enum/const inside items for simple arrays
35+ onUpdate ( {
36+ items : {
37+ ...attribute . items ,
38+ ...updates ,
39+ } ,
40+ } ) ;
41+ } else {
42+ onUpdate ( updates ) ;
43+ }
44+ } ;
2245
2346 // Handle Const field blur - parse and update parent state
2447 const handleConstBlur = ( ) => {
2548 if ( ! constInput ) {
26- onUpdate ( { const : undefined } ) ;
49+ updateValueConstraint ( { const : undefined } ) ;
2750 return ;
2851 }
29- const parsed = parseInputValue ( constInput , attribute . type ) ;
30- onUpdate ( { const : parsed } ) ;
52+ const parsed = parseInputValue ( constInput , effectiveType ) ;
53+ updateValueConstraint ( { const : parsed } ) ;
3154 } ;
3255
3356 // Handle Enum field blur - parse and update parent state
@@ -36,66 +59,101 @@ const ValueConstraints = ({ attribute, onUpdate }) => {
3659 if ( value ) {
3760 try {
3861 const parsed = JSON . parse ( `[${ value } ]` ) ;
39- onUpdate ( { enum : parsed } ) ;
62+ updateValueConstraint ( { enum : parsed } ) ;
4063 } catch {
4164 const enumValues = value
4265 . split ( ',' )
4366 . map ( ( v ) => v . trim ( ) )
4467 . filter ( ( v ) => v ) ;
45- onUpdate ( { enum : enumValues . length > 0 ? enumValues : undefined } ) ;
68+ updateValueConstraint ( { enum : enumValues . length > 0 ? enumValues : undefined } ) ;
4669 }
4770 // Clear the input after successful processing
4871 setEnumInput ( '' ) ;
4972 }
5073 } ;
5174
75+ // Get placeholder examples based on effective type
76+ const getEnumPlaceholder = ( ) => {
77+ switch ( effectiveType ) {
78+ case 'number' :
79+ case 'integer' :
80+ return 'e.g., 1, 2, 3' ;
81+ case 'boolean' :
82+ return 'e.g., true, false' ;
83+ default :
84+ return 'e.g., active, pending, completed' ;
85+ }
86+ } ;
87+
88+ const getConstPlaceholder = ( ) => {
89+ switch ( effectiveType ) {
90+ case 'number' :
91+ case 'integer' :
92+ return 'e.g., 42' ;
93+ case 'boolean' :
94+ return 'e.g., true' ;
95+ default :
96+ return 'e.g., active' ;
97+ }
98+ } ;
99+
100+ // Build description with JSON Schema context
101+ const enumDescription = isSimpleArray
102+ ? 'Allowed values for each item in the array (JSON Schema enum). Comma-separated list.'
103+ : 'Allowed values for this field (JSON Schema enum). Comma-separated list.' ;
104+
105+ const constDescription = isSimpleArray
106+ ? 'Each item in the array must be exactly this value (JSON Schema const).'
107+ : 'Field must be exactly this value (JSON Schema const).' ;
108+
52109 return (
53110 < >
54- < Header variant = "h4" > Value Constraints</ Header >
111+ < Header variant = "h4" > Value Constraints (JSON Schema) </ Header >
55112
56- < FormField label = "Const (Single Constant Value)" description = "Field must be exactly this value" >
113+ < FormField label = "Const (Single Constant Value)" description = { constDescription } constraintText = { `Example: ${ getConstPlaceholder ( ) } ` } >
57114 < Input
58115 value = { constInput }
59116 onChange = { ( { detail } ) => setConstInput ( detail . value ) }
60117 onBlur = { handleConstBlur }
61- placeholder = 'e.g., "active", 42, or JSON value'
62- disabled = { attribute . enum && attribute . enum . length > 0 }
118+ placeholder = { getConstPlaceholder ( ) }
119+ disabled = { currentEnum && currentEnum . length > 0 }
63120 />
64121 </ FormField >
65122
66123 < FormField
67- label = "Enum Values (Multiple Allowed Values)"
68- description = "Comma-separated list of allowed values (mutually exclusive with const)"
124+ label = "Enum (Allowed Values)"
125+ description = { enumDescription }
126+ constraintText = { `Example: ${ getEnumPlaceholder ( ) } - Values are comma-separated` }
69127 >
70- { attribute . enum && attribute . enum . length > 0 ? (
128+ { currentEnum && currentEnum . length > 0 ? (
71129 < SpaceBetween size = "xs" >
72130 < TokenGroup
73- items = { attribute . enum . map ( ( val ) => ( {
131+ items = { currentEnum . map ( ( val ) => ( {
74132 label : typeof val === 'object' ? JSON . stringify ( val ) : String ( val ) ,
75133 dismissLabel : `Remove ${ val } ` ,
76134 } ) ) }
77135 onDismiss = { ( { detail : { itemIndex } } ) => {
78- const newEnum = [ ...( attribute . enum || [ ] ) ] ;
136+ const newEnum = [ ...( currentEnum || [ ] ) ] ;
79137 newEnum . splice ( itemIndex , 1 ) ;
80- onUpdate ( { enum : newEnum . length > 0 ? newEnum : undefined } ) ;
138+ updateValueConstraint ( { enum : newEnum . length > 0 ? newEnum : undefined } ) ;
81139 } }
82140 />
83141 < Button
84142 variant = "link"
85143 onClick = { ( ) => {
86- onUpdate ( { enum : undefined } ) ;
144+ updateValueConstraint ( { enum : undefined } ) ;
87145 } }
88146 >
89147 Clear all enum values
90148 </ Button >
91149 </ SpaceBetween >
92150 ) : (
93151 < Input
94- placeholder = "value1, value2, value3"
152+ placeholder = { getEnumPlaceholder ( ) }
95153 value = { enumInput }
96154 onChange = { ( { detail } ) => setEnumInput ( detail . value ) }
97155 onBlur = { handleEnumBlur }
98- disabled = { attribute . const !== undefined }
156+ disabled = { currentConst !== undefined }
99157 />
100158 ) }
101159 </ FormField >
@@ -108,6 +166,12 @@ ValueConstraints.propTypes = {
108166 type : PropTypes . string ,
109167 const : PropTypes . oneOfType ( [ PropTypes . string , PropTypes . number , PropTypes . bool , PropTypes . object , PropTypes . array ] ) ,
110168 enum : PropTypes . arrayOf ( PropTypes . oneOfType ( [ PropTypes . string , PropTypes . number , PropTypes . bool , PropTypes . object , PropTypes . array ] ) ) ,
169+ items : PropTypes . shape ( {
170+ type : PropTypes . string ,
171+ $ref : PropTypes . string ,
172+ const : PropTypes . oneOfType ( [ PropTypes . string , PropTypes . number , PropTypes . bool , PropTypes . object , PropTypes . array ] ) ,
173+ enum : PropTypes . arrayOf ( PropTypes . oneOfType ( [ PropTypes . string , PropTypes . number , PropTypes . bool , PropTypes . object , PropTypes . array ] ) ) ,
174+ } ) ,
111175 } ) . isRequired ,
112176 onUpdate : PropTypes . func . isRequired ,
113177} ;
0 commit comments