@@ -38,6 +38,16 @@ final Map<String, JsonComponentDefinition> standardComponentDefinitions =
3838 description: 'Horizontal layout for children widgets.' ,
3939 props: < String , JsonPropDefinition > {
4040 'spacing' : JsonPropDefinition (type: 'number' , defaultValue: 0 ),
41+ 'runSpacing' : JsonPropDefinition (
42+ type: 'number' ,
43+ description: 'Used when overflow is set to "wrap".' ,
44+ ),
45+ 'overflow' : JsonPropDefinition (
46+ type: 'string' ,
47+ enumValues: < String > ['row' , 'wrap' , 'scroll' ],
48+ defaultValue: 'row' ,
49+ description: 'How to handle narrow widths.' ,
50+ ),
4151 'mainAxisAlignment' : JsonPropDefinition (type: 'string' ),
4252 'crossAxisAlignment' : JsonPropDefinition (type: 'string' ),
4353 'mainAxisSize' : JsonPropDefinition (
@@ -135,14 +145,31 @@ Map<String, JsonComponentBuilder> standardComponentBuilders() {
135145 },
136146 'Row' : (context) {
137147 final spacing = _toDouble (context.props['spacing' ]) ?? 0 ;
148+ final overflow = _parseRowOverflow (context.props['overflow' ]);
149+
150+ if (overflow == _RowOverflowBehavior .wrap) {
151+ return Wrap (
152+ spacing: spacing,
153+ runSpacing: _toDouble (context.props['runSpacing' ]) ?? spacing,
154+ alignment: _parseWrapAlignment (context.props['mainAxisAlignment' ]),
155+ crossAxisAlignment: _parseWrapCrossAlignment (
156+ context.props['crossAxisAlignment' ],
157+ ),
158+ children: context.children,
159+ );
160+ }
161+
138162 final children = _withSpacing (
139163 context.children,
140164 spacing: spacing,
141165 axis: Axis .horizontal,
142166 );
143167
144- return Row (
145- mainAxisSize: _parseMainAxisSize (context.props['mainAxisSize' ]),
168+ final row = Row (
169+ // Horizontal scroll views provide unconstrained width, so max is invalid.
170+ mainAxisSize: overflow == _RowOverflowBehavior .scroll
171+ ? MainAxisSize .min
172+ : _parseMainAxisSize (context.props['mainAxisSize' ]),
146173 mainAxisAlignment: _parseMainAxisAlignment (
147174 context.props['mainAxisAlignment' ],
148175 ),
@@ -151,6 +178,15 @@ Map<String, JsonComponentBuilder> standardComponentBuilders() {
151178 ),
152179 children: children,
153180 );
181+
182+ if (overflow == _RowOverflowBehavior .scroll) {
183+ return SingleChildScrollView (
184+ scrollDirection: Axis .horizontal,
185+ child: row,
186+ );
187+ }
188+
189+ return row;
154190 },
155191 'Container' : (context) {
156192 final width = _toDouble (context.props['width' ]);
@@ -465,3 +501,44 @@ int? _toInt(dynamic raw) {
465501 if (raw is num ) return raw.toInt ();
466502 return int .tryParse (raw? .toString () ?? '' );
467503}
504+
505+ enum _RowOverflowBehavior { row, wrap, scroll }
506+
507+ _RowOverflowBehavior _parseRowOverflow (dynamic raw) {
508+ switch (raw? .toString ()) {
509+ case 'wrap' :
510+ return _RowOverflowBehavior .wrap;
511+ case 'scroll' :
512+ return _RowOverflowBehavior .scroll;
513+ default :
514+ return _RowOverflowBehavior .row;
515+ }
516+ }
517+
518+ WrapAlignment _parseWrapAlignment (dynamic raw) {
519+ switch (raw? .toString ()) {
520+ case 'end' :
521+ return WrapAlignment .end;
522+ case 'center' :
523+ return WrapAlignment .center;
524+ case 'spaceBetween' :
525+ return WrapAlignment .spaceBetween;
526+ case 'spaceAround' :
527+ return WrapAlignment .spaceAround;
528+ case 'spaceEvenly' :
529+ return WrapAlignment .spaceEvenly;
530+ default :
531+ return WrapAlignment .start;
532+ }
533+ }
534+
535+ WrapCrossAlignment _parseWrapCrossAlignment (dynamic raw) {
536+ switch (raw? .toString ()) {
537+ case 'end' :
538+ return WrapCrossAlignment .end;
539+ case 'center' :
540+ return WrapCrossAlignment .center;
541+ default :
542+ return WrapCrossAlignment .start;
543+ }
544+ }
0 commit comments