diff --git a/docs/docs.json b/docs/docs.json
index 0475eea04..81148c351 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -74,6 +74,8 @@
"widgets/flexible",
"widgets/fitted_box",
"widgets/fractionally_sized_box",
+ "widgets/intrinsic_height",
+ "widgets/intrinsic_width",
"widgets/limited_box",
"widgets/padding",
"widgets/positioned",
diff --git a/docs/widgets/intrinsic_height.mdx b/docs/widgets/intrinsic_height.mdx
new file mode 100644
index 000000000..0e6a05860
--- /dev/null
+++ b/docs/widgets/intrinsic_height.mdx
@@ -0,0 +1,151 @@
+---
+title: "IntrinsicHeight"
+description: "Documentation for IntrinsicHeight"
+---
+
+import { PLAYGROUND_BASE_URL } from "/snippets/playground_base.mdx";
+
+export const intrinsicHeightPreviewJson = {
+ "type": "intrinsicHeight",
+ "child": {
+ "type": "row",
+ "crossAxisAlignment": "stretch",
+ "children": [
+ {
+ "type": "container",
+ "width": 60,
+ "color": "#FF5733",
+ "child": {
+ "type": "text",
+ "data": "Short"
+ }
+ },
+ {
+ "type": "container",
+ "width": 60,
+ "color": "#33A1FF",
+ "child": {
+ "type": "text",
+ "data": "A much longer piece of text"
+ }
+ }
+ ]
+ }
+};
+export const intrinsicHeightPreviewSrc = `${PLAYGROUND_BASE_URL}/embed`;
+
+The Stac IntrinsicHeight allows you to build a Flutter intrinsic height widget using JSON.
+To know more about the intrinsic height widget in Flutter, refer to the [official documentation](https://api.flutter.dev/flutter/widgets/IntrinsicHeight-class.html).
+
+`IntrinsicHeight` sizes its child to the child's maximum intrinsic height. It is most useful
+inside a `row` that uses `crossAxisAlignment: stretch`, when the row itself sits somewhere
+with an unbounded height — for example inside a horizontally scrolling
+`singleChildScrollView` that is itself inside a vertically scrolling list. In that situation
+`stretch` has no finite height to stretch its children into and layout fails; wrapping the
+`row` in `intrinsicHeight` computes a real height first, so every child of the row ends up
+the same height as the tallest one.
+
+
+`intrinsicHeight` is relatively expensive because it performs a speculative extra layout
+pass before the final layout. Prefer giving the child a fixed height where you can, and
+reach for `intrinsicHeight` only when the height genuinely needs to be computed from the
+content.
+
+
+## Properties
+
+| Property | Type | Description |
+|----------|--------------|----------------------------------------------------------|
+| child | `StacWidget` | The widget to size to its own maximum intrinsic height. |
+
+## Example
+
+
+
+
+```dart
+StacIntrinsicHeight(
+ child: StacRow(
+ crossAxisAlignment: StacCrossAxisAlignment.stretch,
+ children: [
+ StacContainer(
+ width: 60,
+ color: StacColors.deepOrange,
+ child: StacText(data: 'Short'),
+ ),
+ StacContainer(
+ width: 60,
+ color: StacColors.blue,
+ child: StacText(data: 'A much longer piece of text'),
+ ),
+ ],
+ ),
+)
+```
+
+
+
+
+```json
+{
+ "type": "intrinsicHeight",
+ "child": {
+ "type": "row",
+ "crossAxisAlignment": "stretch",
+ "children": [
+ {
+ "type": "container",
+ "width": 60,
+ "color": "#FF5733",
+ "child": {
+ "type": "text",
+ "data": "Short"
+ }
+ },
+ {
+ "type": "container",
+ "width": 60,
+ "color": "#33A1FF",
+ "child": {
+ "type": "text",
+ "data": "A much longer piece of text"
+ }
+ }
+ ]
+ }
+}
+```
+
+
+
+
+
+
diff --git a/docs/widgets/intrinsic_width.mdx b/docs/widgets/intrinsic_width.mdx
new file mode 100644
index 000000000..3ad23ef7b
--- /dev/null
+++ b/docs/widgets/intrinsic_width.mdx
@@ -0,0 +1,150 @@
+---
+title: "IntrinsicWidth"
+description: "Documentation for IntrinsicWidth"
+---
+
+import { PLAYGROUND_BASE_URL } from "/snippets/playground_base.mdx";
+
+export const intrinsicWidthPreviewJson = {
+ "type": "intrinsicWidth",
+ "child": {
+ "type": "column",
+ "crossAxisAlignment": "stretch",
+ "children": [
+ {
+ "type": "container",
+ "height": 40,
+ "color": "#FF5733",
+ "child": {
+ "type": "text",
+ "data": "Short"
+ }
+ },
+ {
+ "type": "container",
+ "height": 40,
+ "color": "#33A1FF",
+ "child": {
+ "type": "text",
+ "data": "A much longer piece of text"
+ }
+ }
+ ]
+ }
+};
+export const intrinsicWidthPreviewSrc = `${PLAYGROUND_BASE_URL}/embed`;
+
+The Stac IntrinsicWidth allows you to build a Flutter intrinsic width widget using JSON.
+To know more about the intrinsic width widget in Flutter, refer to the [official documentation](https://api.flutter.dev/flutter/widgets/IntrinsicWidth-class.html).
+
+`IntrinsicWidth` sizes its child to the child's maximum intrinsic width. It is the
+horizontal counterpart of [IntrinsicHeight](/widgets/intrinsic_height) and solves the same
+problem along the other axis — for example a `column` using `crossAxisAlignment: stretch`
+that sits somewhere with an unbounded width.
+
+
+`intrinsicWidth` is relatively expensive because it performs a speculative extra layout
+pass before the final layout. Prefer giving the child a fixed width where you can, and
+reach for `intrinsicWidth` only when the width genuinely needs to be computed from the
+content.
+
+
+## Properties
+
+| Property | Type | Description |
+|------------|--------------|-----------------------------------------------------------------------|
+| stepWidth | `double` | If set, forces the child's width to be a multiple of this value. |
+| stepHeight | `double` | If set, forces the child's height to be a multiple of this value. |
+| child | `StacWidget` | The widget to size to its own maximum intrinsic width. |
+
+## Example
+
+
+
+
+```dart
+StacIntrinsicWidth(
+ child: StacColumn(
+ crossAxisAlignment: StacCrossAxisAlignment.stretch,
+ children: [
+ StacContainer(
+ height: 40,
+ color: StacColors.deepOrange,
+ child: StacText(data: 'Short'),
+ ),
+ StacContainer(
+ height: 40,
+ color: StacColors.blue,
+ child: StacText(data: 'A much longer piece of text'),
+ ),
+ ],
+ ),
+)
+```
+
+
+
+
+```json
+{
+ "type": "intrinsicWidth",
+ "child": {
+ "type": "column",
+ "crossAxisAlignment": "stretch",
+ "children": [
+ {
+ "type": "container",
+ "height": 40,
+ "color": "#FF5733",
+ "child": {
+ "type": "text",
+ "data": "Short"
+ }
+ },
+ {
+ "type": "container",
+ "height": 40,
+ "color": "#33A1FF",
+ "child": {
+ "type": "text",
+ "data": "A much longer piece of text"
+ }
+ }
+ ]
+ }
+}
+```
+
+
+
+
+
+
diff --git a/packages/stac/lib/src/framework/stac_service.dart b/packages/stac/lib/src/framework/stac_service.dart
index b05ff8249..1d96b4b30 100644
--- a/packages/stac/lib/src/framework/stac_service.dart
+++ b/packages/stac/lib/src/framework/stac_service.dart
@@ -130,6 +130,8 @@ class StacService {
const StacAspectRatioParser(),
const StacFittedBoxParser(),
const StacLimitedBoxParser(),
+ const StacIntrinsicHeightParser(),
+ const StacIntrinsicWidthParser(),
const StacDynamicViewParser(),
const StacDropdownMenuParser(),
const StacClipRRectParser(),
diff --git a/packages/stac/lib/src/parsers/widgets/stac_intrinsic_height/stac_intrinsic_height_parser.dart b/packages/stac/lib/src/parsers/widgets/stac_intrinsic_height/stac_intrinsic_height_parser.dart
new file mode 100644
index 000000000..cfbe90d59
--- /dev/null
+++ b/packages/stac/lib/src/parsers/widgets/stac_intrinsic_height/stac_intrinsic_height_parser.dart
@@ -0,0 +1,20 @@
+import 'package:flutter/material.dart';
+import 'package:stac/src/parsers/core/stac_widget_parser.dart';
+import 'package:stac_framework/stac_framework.dart';
+import 'package:stac_core/widgets/intrinsic_height/stac_intrinsic_height.dart';
+
+class StacIntrinsicHeightParser extends StacParser {
+ const StacIntrinsicHeightParser();
+
+ @override
+ String get type => StacIntrinsicHeight().type;
+
+ @override
+ StacIntrinsicHeight getModel(Map json) =>
+ StacIntrinsicHeight.fromJson(json);
+
+ @override
+ Widget parse(BuildContext context, StacIntrinsicHeight model) {
+ return IntrinsicHeight(child: model.child.parse(context));
+ }
+}
diff --git a/packages/stac/lib/src/parsers/widgets/stac_intrinsic_width/stac_intrinsic_width_parser.dart b/packages/stac/lib/src/parsers/widgets/stac_intrinsic_width/stac_intrinsic_width_parser.dart
new file mode 100644
index 000000000..cda86038a
--- /dev/null
+++ b/packages/stac/lib/src/parsers/widgets/stac_intrinsic_width/stac_intrinsic_width_parser.dart
@@ -0,0 +1,24 @@
+import 'package:flutter/material.dart';
+import 'package:stac/src/parsers/core/stac_widget_parser.dart';
+import 'package:stac_framework/stac_framework.dart';
+import 'package:stac_core/widgets/intrinsic_width/stac_intrinsic_width.dart';
+
+class StacIntrinsicWidthParser extends StacParser {
+ const StacIntrinsicWidthParser();
+
+ @override
+ String get type => StacIntrinsicWidth().type;
+
+ @override
+ StacIntrinsicWidth getModel(Map json) =>
+ StacIntrinsicWidth.fromJson(json);
+
+ @override
+ Widget parse(BuildContext context, StacIntrinsicWidth model) {
+ return IntrinsicWidth(
+ stepWidth: model.stepWidth,
+ stepHeight: model.stepHeight,
+ child: model.child.parse(context),
+ );
+ }
+}
diff --git a/packages/stac/lib/src/parsers/widgets/widgets.dart b/packages/stac/lib/src/parsers/widgets/widgets.dart
index 7fce7f5b3..c73d750ca 100644
--- a/packages/stac/lib/src/parsers/widgets/widgets.dart
+++ b/packages/stac/lib/src/parsers/widgets/widgets.dart
@@ -42,6 +42,8 @@ export 'package:stac/src/parsers/widgets/stac_hero/stac_hero_parser.dart';
export 'package:stac/src/parsers/widgets/stac_icon/stac_icon_parser.dart';
export 'package:stac/src/parsers/widgets/stac_icon_button/stac_icon_button_parser.dart';
export 'package:stac/src/parsers/widgets/stac_image/stac_image_parser.dart';
+export 'package:stac/src/parsers/widgets/stac_intrinsic_height/stac_intrinsic_height_parser.dart';
+export 'package:stac/src/parsers/widgets/stac_intrinsic_width/stac_intrinsic_width_parser.dart';
export 'package:stac/src/parsers/widgets/stac_limited_box/stac_limited_box_parser.dart';
export 'package:stac/src/parsers/widgets/stac_linear_progress_indicator/stac_linear_progress_indicator_parser.dart';
export 'package:stac/src/parsers/widgets/stac_list_tile/stac_list_tile_parser.dart';
diff --git a/packages/stac_core/lib/foundation/specifications/widget_type.dart b/packages/stac_core/lib/foundation/specifications/widget_type.dart
index 2503b3389..694e64a1c 100644
--- a/packages/stac_core/lib/foundation/specifications/widget_type.dart
+++ b/packages/stac_core/lib/foundation/specifications/widget_type.dart
@@ -142,6 +142,12 @@ enum WidgetType {
/// Ink well widget
inkWell,
+ /// Intrinsic height widget
+ intrinsicHeight,
+
+ /// Intrinsic width widget
+ intrinsicWidth,
+
/// Limited box widget
limitedBox,
diff --git a/packages/stac_core/lib/widgets/intrinsic_height/stac_intrinsic_height.dart b/packages/stac_core/lib/widgets/intrinsic_height/stac_intrinsic_height.dart
new file mode 100644
index 000000000..d3887cc7b
--- /dev/null
+++ b/packages/stac_core/lib/widgets/intrinsic_height/stac_intrinsic_height.dart
@@ -0,0 +1,69 @@
+import 'package:json_annotation/json_annotation.dart';
+import 'package:stac_core/core/stac_widget.dart';
+import 'package:stac_core/foundation/specifications/widget_type.dart';
+
+part 'stac_intrinsic_height.g.dart';
+
+/// A Stac model representing Flutter's [IntrinsicHeight] widget.
+///
+/// A widget that sizes its child to the child's maximum intrinsic height.
+///
+/// This is useful when [child] would otherwise be laid out with an
+/// unbounded height — for example a `row` with `crossAxisAlignment: stretch`
+/// inside a horizontal `singleChildScrollView`, whose own height is
+/// unconstrained because it sits inside a vertically scrolling list.
+/// Without `intrinsicHeight`, `stretch` has no finite height to stretch
+/// into and layout fails; `intrinsicHeight` computes the child's real
+/// maximum intrinsic height first and lays it out with that as a fixed
+/// value.
+///
+/// This class is relatively expensive, because it adds a speculative layout
+/// pass before the final layout phase. Avoid using it where possible. In
+/// the worst case, this widget can result in a layout that is O(N^2) in
+/// the number of widgets in the subtree.
+///
+/// ```dart
+/// StacIntrinsicHeight(
+/// child: StacRow(
+/// crossAxisAlignment: StacCrossAxisAlignment.stretch,
+/// children: [
+/// StacContainer(color: StacColors.red, width: 100),
+/// StacContainer(color: StacColors.blue, width: 100, height: 150),
+/// ],
+/// ),
+/// )
+/// ```
+///
+/// ```json
+/// {
+/// "type": "intrinsicHeight",
+/// "child": {
+/// "type": "row",
+/// "crossAxisAlignment": "stretch",
+/// "children": [
+/// {"type": "container", "color": "#FF0000", "width": 100},
+/// {"type": "container", "color": "#0000FF", "width": 100, "height": 150}
+/// ]
+/// }
+/// }
+/// ```
+@JsonSerializable()
+class StacIntrinsicHeight extends StacWidget {
+ /// Creates a [StacIntrinsicHeight] with the given properties.
+ const StacIntrinsicHeight({this.child});
+
+ /// The widget below this widget in the tree.
+ final StacWidget? child;
+
+ /// Widget type identifier.
+ @override
+ String get type => WidgetType.intrinsicHeight.name;
+
+ /// Creates a [StacIntrinsicHeight] from JSON.
+ factory StacIntrinsicHeight.fromJson(Map json) =>
+ _$StacIntrinsicHeightFromJson(json);
+
+ /// Converts this [StacIntrinsicHeight] to JSON.
+ @override
+ Map toJson() => _$StacIntrinsicHeightToJson(this);
+}
diff --git a/packages/stac_core/lib/widgets/intrinsic_height/stac_intrinsic_height.g.dart b/packages/stac_core/lib/widgets/intrinsic_height/stac_intrinsic_height.g.dart
new file mode 100644
index 000000000..330d49b10
--- /dev/null
+++ b/packages/stac_core/lib/widgets/intrinsic_height/stac_intrinsic_height.g.dart
@@ -0,0 +1,21 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'stac_intrinsic_height.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+StacIntrinsicHeight _$StacIntrinsicHeightFromJson(Map json) =>
+ StacIntrinsicHeight(
+ child: json['child'] == null
+ ? null
+ : StacWidget.fromJson(json['child'] as Map),
+ );
+
+Map _$StacIntrinsicHeightToJson(
+ StacIntrinsicHeight instance,
+) => {
+ 'child': instance.child?.toJson(),
+ 'type': instance.type,
+};
diff --git a/packages/stac_core/lib/widgets/intrinsic_width/stac_intrinsic_width.dart b/packages/stac_core/lib/widgets/intrinsic_width/stac_intrinsic_width.dart
new file mode 100644
index 000000000..9e7551e52
--- /dev/null
+++ b/packages/stac_core/lib/widgets/intrinsic_width/stac_intrinsic_width.dart
@@ -0,0 +1,72 @@
+import 'package:json_annotation/json_annotation.dart';
+import 'package:stac_core/core/converters/double_converter.dart';
+import 'package:stac_core/core/stac_widget.dart';
+import 'package:stac_core/foundation/specifications/widget_type.dart';
+
+part 'stac_intrinsic_width.g.dart';
+
+/// A Stac model representing Flutter's [IntrinsicWidth] widget.
+///
+/// A widget that sizes its child to the child's maximum intrinsic width.
+///
+/// Analogous to [StacIntrinsicHeight] but along the horizontal axis. This
+/// is useful when [child] would otherwise be laid out with an unbounded
+/// width — for example a `column` with `crossAxisAlignment: stretch`
+/// inside a horizontally scrolling widget.
+///
+/// This class is relatively expensive, because it adds a speculative layout
+/// pass before the final layout phase. Avoid using it where possible.
+///
+/// ```dart
+/// StacIntrinsicWidth(
+/// child: StacColumn(
+/// crossAxisAlignment: StacCrossAxisAlignment.stretch,
+/// children: [
+/// StacText(data: 'Short'),
+/// StacText(data: 'A much longer line of text'),
+/// ],
+/// ),
+/// )
+/// ```
+///
+/// ```json
+/// {
+/// "type": "intrinsicWidth",
+/// "child": {
+/// "type": "column",
+/// "crossAxisAlignment": "stretch",
+/// "children": [
+/// {"type": "text", "data": "Short"},
+/// {"type": "text", "data": "A much longer line of text"}
+/// ]
+/// }
+/// }
+/// ```
+@JsonSerializable()
+class StacIntrinsicWidth extends StacWidget {
+ /// Creates a [StacIntrinsicWidth] with the given properties.
+ const StacIntrinsicWidth({this.stepWidth, this.stepHeight, this.child});
+
+ /// If non-null, force the child's width to be a multiple of this value.
+ @DoubleConverter()
+ final double? stepWidth;
+
+ /// If non-null, force the child's height to be a multiple of this value.
+ @DoubleConverter()
+ final double? stepHeight;
+
+ /// The widget below this widget in the tree.
+ final StacWidget? child;
+
+ /// Widget type identifier.
+ @override
+ String get type => WidgetType.intrinsicWidth.name;
+
+ /// Creates a [StacIntrinsicWidth] from JSON.
+ factory StacIntrinsicWidth.fromJson(Map json) =>
+ _$StacIntrinsicWidthFromJson(json);
+
+ /// Converts this [StacIntrinsicWidth] to JSON.
+ @override
+ Map toJson() => _$StacIntrinsicWidthToJson(this);
+}
diff --git a/packages/stac_core/lib/widgets/intrinsic_width/stac_intrinsic_width.g.dart b/packages/stac_core/lib/widgets/intrinsic_width/stac_intrinsic_width.g.dart
new file mode 100644
index 000000000..45ff9fa36
--- /dev/null
+++ b/packages/stac_core/lib/widgets/intrinsic_width/stac_intrinsic_width.g.dart
@@ -0,0 +1,24 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'stac_intrinsic_width.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+StacIntrinsicWidth _$StacIntrinsicWidthFromJson(Map json) =>
+ StacIntrinsicWidth(
+ stepWidth: const DoubleConverter().fromJson(json['stepWidth']),
+ stepHeight: const DoubleConverter().fromJson(json['stepHeight']),
+ child: json['child'] == null
+ ? null
+ : StacWidget.fromJson(json['child'] as Map),
+ );
+
+Map _$StacIntrinsicWidthToJson(StacIntrinsicWidth instance) =>
+ {
+ 'stepWidth': const DoubleConverter().toJson(instance.stepWidth),
+ 'stepHeight': const DoubleConverter().toJson(instance.stepHeight),
+ 'child': instance.child?.toJson(),
+ 'type': instance.type,
+ };
diff --git a/packages/stac_core/lib/widgets/widgets.dart b/packages/stac_core/lib/widgets/widgets.dart
index fe4061ee3..67578845e 100644
--- a/packages/stac_core/lib/widgets/widgets.dart
+++ b/packages/stac_core/lib/widgets/widgets.dart
@@ -46,6 +46,8 @@ export 'icon/stac_icons.dart';
export 'icon_button/stac_icon_button.dart';
export 'image/stac_image.dart';
export 'ink_well/stac_ink_well.dart';
+export 'intrinsic_height/stac_intrinsic_height.dart';
+export 'intrinsic_width/stac_intrinsic_width.dart';
export 'limited_box/stac_limited_box.dart';
export 'linear_progress_indicator/stac_linear_progress_indicator.dart';
export 'list_tile/stac_list_tile.dart';
diff --git a/stac_playground/assets/json/intrinsic_height_example.json b/stac_playground/assets/json/intrinsic_height_example.json
new file mode 100644
index 000000000..99a2a9537
--- /dev/null
+++ b/stac_playground/assets/json/intrinsic_height_example.json
@@ -0,0 +1,68 @@
+{
+ "type": "scaffold",
+ "appBar": {
+ "type": "appBar",
+ "title": {
+ "type": "text",
+ "data": "IntrinsicHeight"
+ }
+ },
+ "body": {
+ "type": "padding",
+ "padding": 16,
+ "child": {
+ "type": "singleChildScrollView",
+ "scrollDirection": "horizontal",
+ "child": {
+ "type": "intrinsicHeight",
+ "child": {
+ "type": "row",
+ "crossAxisAlignment": "stretch",
+ "children": [
+ {
+ "type": "container",
+ "width": 120,
+ "margin": { "right": 12 },
+ "padding": 12,
+ "decoration": {
+ "color": "#FFE0B2",
+ "borderRadius": 8
+ },
+ "child": {
+ "type": "text",
+ "data": "Short label"
+ }
+ },
+ {
+ "type": "container",
+ "width": 120,
+ "margin": { "right": 12 },
+ "padding": 12,
+ "decoration": {
+ "color": "#B2DFDB",
+ "borderRadius": 8
+ },
+ "child": {
+ "type": "text",
+ "data": "A card with a lot more text in it, so it grows much taller than its neighbours"
+ }
+ },
+ {
+ "type": "container",
+ "width": 120,
+ "padding": 12,
+ "decoration": {
+ "color": "#C5CAE9",
+ "borderRadius": 8
+ },
+ "child": {
+ "type": "text",
+ "data": "Medium length label here"
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+}
diff --git a/stac_playground/assets/json/intrinsic_width_example.json b/stac_playground/assets/json/intrinsic_width_example.json
new file mode 100644
index 000000000..a8649d71c
--- /dev/null
+++ b/stac_playground/assets/json/intrinsic_width_example.json
@@ -0,0 +1,50 @@
+{
+ "type": "scaffold",
+ "appBar": {
+ "type": "appBar",
+ "title": {
+ "type": "text",
+ "data": "IntrinsicWidth"
+ }
+ },
+ "body": {
+ "type": "padding",
+ "padding": 16,
+ "child": {
+ "type": "intrinsicWidth",
+ "child": {
+ "type": "column",
+ "crossAxisAlignment": "stretch",
+ "children": [
+ {
+ "type": "container",
+ "height": 40,
+ "margin": { "bottom": 12 },
+ "padding": 12,
+ "decoration": {
+ "color": "#FFE0B2",
+ "borderRadius": 8
+ },
+ "child": {
+ "type": "text",
+ "data": "Short"
+ }
+ },
+ {
+ "type": "container",
+ "height": 40,
+ "padding": 12,
+ "decoration": {
+ "color": "#B2DFDB",
+ "borderRadius": 8
+ },
+ "child": {
+ "type": "text",
+ "data": "A much longer piece of text"
+ }
+ }
+ ]
+ }
+ }
+ }
+}
diff --git a/stac_playground/lib/data/component_entries.dart b/stac_playground/lib/data/component_entries.dart
index 30bfdf249..bc5e75e8d 100644
--- a/stac_playground/lib/data/component_entries.dart
+++ b/stac_playground/lib/data/component_entries.dart
@@ -724,6 +724,26 @@ const List componentEntries = [
iconType: 'material',
category: EntryCategory.component,
),
+ PlaygroundEntry(
+ id: 'intrinsic_height',
+ title: 'Stac IntrinsicHeight',
+ description: 'A Material Design Stac IntrinsicHeight widget',
+ jsonAsset: 'assets/json/intrinsic_height_example.json',
+ dartAsset: 'lib/dsl/intrinsic_height.dart',
+ icon: 'apartment',
+ iconType: 'material',
+ category: EntryCategory.component,
+ ),
+ PlaygroundEntry(
+ id: 'intrinsic_width',
+ title: 'Stac IntrinsicWidth',
+ description: 'A Material Design Stac IntrinsicWidth widget',
+ jsonAsset: 'assets/json/intrinsic_width_example.json',
+ dartAsset: 'lib/dsl/intrinsic_width.dart',
+ icon: 'apartment',
+ iconType: 'material',
+ category: EntryCategory.component,
+ ),
PlaygroundEntry(
id: 'dynamic_view',
title: 'Stac Dynamic View',
diff --git a/stac_playground/lib/data/dsl_to_json.dart b/stac_playground/lib/data/dsl_to_json.dart
index 208747a67..9dd4fb349 100644
--- a/stac_playground/lib/data/dsl_to_json.dart
+++ b/stac_playground/lib/data/dsl_to_json.dart
@@ -107,6 +107,8 @@ const Set _widgetClasses = {
'StacIconButton',
'StacImage',
'StacInkWell',
+ 'StacIntrinsicHeight',
+ 'StacIntrinsicWidth',
'StacLimitedBox',
'StacLinearProgressIndicator',
'StacListTile',
diff --git a/stac_playground/lib/dsl/intrinsic_height.dart b/stac_playground/lib/dsl/intrinsic_height.dart
new file mode 100644
index 000000000..f59c840c7
--- /dev/null
+++ b/stac_playground/lib/dsl/intrinsic_height.dart
@@ -0,0 +1,53 @@
+import 'package:stac_core/stac_core.dart';
+
+@StacScreen(screenName: 'intrinsic_height')
+StacWidget intrinsicHeightExample() {
+ return StacScaffold(
+ appBar: StacAppBar(title: StacText(data: 'IntrinsicHeight')),
+ body: StacPadding(
+ padding: const StacEdgeInsets.all(16),
+ child: StacSingleChildScrollView(
+ scrollDirection: StacAxis.horizontal,
+ child: StacIntrinsicHeight(
+ child: StacRow(
+ crossAxisAlignment: StacCrossAxisAlignment.stretch,
+ children: [
+ StacContainer(
+ width: 120,
+ margin: const StacEdgeInsets.only(right: 12),
+ padding: const StacEdgeInsets.all(12),
+ decoration: const StacBoxDecoration(
+ color: '#FFE0B2',
+ borderRadius: StacBorderRadius.circular(8),
+ ),
+ child: StacText(data: 'Short label'),
+ ),
+ StacContainer(
+ width: 120,
+ margin: const StacEdgeInsets.only(right: 12),
+ padding: const StacEdgeInsets.all(12),
+ decoration: const StacBoxDecoration(
+ color: '#B2DFDB',
+ borderRadius: StacBorderRadius.circular(8),
+ ),
+ child: StacText(
+ data:
+ 'A card with a lot more text in it, so it grows much taller than its neighbours',
+ ),
+ ),
+ StacContainer(
+ width: 120,
+ padding: const StacEdgeInsets.all(12),
+ decoration: const StacBoxDecoration(
+ color: '#C5CAE9',
+ borderRadius: StacBorderRadius.circular(8),
+ ),
+ child: StacText(data: 'Medium length label here'),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ),
+ );
+}
diff --git a/stac_playground/lib/dsl/intrinsic_width.dart b/stac_playground/lib/dsl/intrinsic_width.dart
new file mode 100644
index 000000000..8b6c3c1ab
--- /dev/null
+++ b/stac_playground/lib/dsl/intrinsic_width.dart
@@ -0,0 +1,37 @@
+import 'package:stac_core/stac_core.dart';
+
+@StacScreen(screenName: 'intrinsic_width')
+StacWidget intrinsicWidthExample() {
+ return StacScaffold(
+ appBar: StacAppBar(title: StacText(data: 'IntrinsicWidth')),
+ body: StacPadding(
+ padding: const StacEdgeInsets.all(16),
+ child: StacIntrinsicWidth(
+ child: StacColumn(
+ crossAxisAlignment: StacCrossAxisAlignment.stretch,
+ children: [
+ StacContainer(
+ height: 40,
+ margin: const StacEdgeInsets.only(bottom: 12),
+ padding: const StacEdgeInsets.all(12),
+ decoration: const StacBoxDecoration(
+ color: '#FFE0B2',
+ borderRadius: StacBorderRadius.circular(8),
+ ),
+ child: StacText(data: 'Short'),
+ ),
+ StacContainer(
+ height: 40,
+ padding: const StacEdgeInsets.all(12),
+ decoration: const StacBoxDecoration(
+ color: '#B2DFDB',
+ borderRadius: StacBorderRadius.circular(8),
+ ),
+ child: StacText(data: 'A much longer piece of text'),
+ ),
+ ],
+ ),
+ ),
+ ),
+ );
+}
diff --git a/tools/stac-vscode/src/generated/widgetCatalog.ts b/tools/stac-vscode/src/generated/widgetCatalog.ts
index 103fc19d7..5d5c9bf13 100644
--- a/tools/stac-vscode/src/generated/widgetCatalog.ts
+++ b/tools/stac-vscode/src/generated/widgetCatalog.ts
@@ -272,6 +272,18 @@ export const widgetCatalog: WidgetCatalogEntry[] = [
"supportsChild": true,
"supportsChildren": false
},
+ {
+ "className": "StacIntrinsicHeight",
+ "slug": "intrinsic_height",
+ "supportsChild": true,
+ "supportsChildren": false
+ },
+ {
+ "className": "StacIntrinsicWidth",
+ "slug": "intrinsic_width",
+ "supportsChild": true,
+ "supportsChildren": false
+ },
{
"className": "StacLimitedBox",
"slug": "limited_box",