Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@Potatomonsta
Copy link
Contributor

@Potatomonsta Potatomonsta commented Sep 20, 2025

Updated StacTextStyle and StacGradient

Description

Updated StacTextStyle to maintain existing json format
Updated StacGradient to have Flutter like constructors

Type of Change

  • New feature (non-breaking change which adds functionality)
  • Bug fix (non-breaking change which fixes an issue)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Code refactor
  • Build configuration change
  • Documentation
  • Chore

Summary by CodeRabbit

  • New Features
    • Theme-based text styles with optional custom overrides and per-child styling.
    • New gradient types (linear, radial, sweep) with simpler configuration.
  • Improvements
    • Onboarding screen now supports a linear gradient.
    • Button themes explicitly use rounded rectangle shapes for consistency.
    • More robust text style parsing and optional children handling in text elements.
  • Documentation
    • Updated examples for gradients and text styling.
  • Chores
    • Added a logging dependency to support improved diagnostics.

Updated StacTextStyle and StacGradient
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 20, 2025

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This change introduces new gradient constructors, overhauls text style modeling to a discriminated union with converters, updates text parsing and style resolution, adjusts text widget JSON (including optional children and copyWithStyle), tweaks example assets and theming JSON, and adds a logging dependency.

Changes

Cohort / File(s) Summary of changes
Example assets and theme JSON
examples/movie_app/assets/jsons/screens/onboarding_screen.json, examples/movie_app/lib/main.dart
Added gradientType: "linear" in onboarding JSON; renamed a text node field from data to text. In dark theme JSON, added shape.type: "roundedRectangleBorder" for filled and outlined button themes.
Text style model and serialization
packages/stac_core/lib/foundation/text/stac_text_style/stac_text_style.dart, packages/stac_core/lib/foundation/text/stac_text_style/stac_text_style.g.dart, packages/stac_core/lib/core/converters/stac_text_style_converter.dart, packages/stac_core/lib/foundation/text/stac_text_span/stac_text_span.dart, packages/stac_core/lib/foundation/text/stac_text_span/stac_text_span.g.dart
Introduced StacTextStyleType and StacMaterialTextStyle enums; added StacCustomTextStyle and StacThemeTextStyle; updated JSON (de)serialization with type discriminator and material text theme mapping; added StacTextStyleConverter and applied it to StacTextSpan style field.
Text widget model and JSON
packages/stac_core/lib/widgets/text/stac_text.dart, packages/stac_core/lib/widgets/text/stac_text.g.dart
Added optional copyWithStyle (with converter); made children nullable; changed type getter to return 'text'; added fromJson/toJson; updated generated JSON to use converter and handle nullability.
Parsers (runtime resolution)
packages/stac/lib/src/parsers/painting/stac_text_style_parser.dart, packages/stac/lib/src/parsers/widgets/stac_text/stac_text_parser.dart
TextStyle parser now returns TextStyle? with branches for theme-based and custom styles. Text parser now resolves style via a new _resolveStyle, supports per-child style, and null-safe children handling; imports narrowed.
Gradient API
packages/stac_core/lib/foundation/effects/stac_gradient/stac_gradient.dart
Added named constructors: StacGradient.linear, .radial, .sweep; added aliases StacLinearGradient, StacRadialGradient, StacSweepGradient; documented API; set/clear fields per gradient type.
Dependency update
packages/stac_core/pubspec.yaml
Added dependency: stac_logger: ^1.1.0.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor App
  participant JSON as JSON Input
  participant Core as StacCore (fromJson)
  participant Conv as StacTextStyleConverter
  participant Widget as StacText
  participant Parser as StacTextParser
  participant StyleP as StacTextStyleParser
  participant Flutter as Flutter Text/Span

  App->>JSON: Provide StacText JSON
  JSON->>Core: StacText.fromJson(json)
  Core->>Conv: style = fromJson(json.style)
  alt style string or map
    Conv-->>Core: StacTextStyle (theme or custom) / null
  else invalid
    Conv-->>Core: null (warn logged)
  end
  Core-->>Widget: StacText(model, copyWithStyle?, children?)
  App->>Parser: parse(model)
  Parser->>Parser: _resolveStyle(model.style, copyWithStyle)
  Parser->>StyleP: style.parse(context)
  alt type = theme
    StyleP-->>Parser: TextTheme-derived TextStyle
  else type = custom
    StyleP-->>Parser: Constructed TextStyle
  else no style
    StyleP-->>Parser: null
  end
  Parser->>Flutter: Build TextSpan tree with per-child styles
  Flutter-->>App: Rendered text
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

A nib of code, I twitch my nose—
New gradients bloom where color flows.
Text learns themes, both small and grand,
With custom threads I weave by hand.
Parsers hop, resolve with grace,
JSON carrots fall in place.
Thump—release across the space! 🥕🐇

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title Check ❓ Inconclusive The title "BugFixes for Stac DSL" is concise but too generic to communicate the primary changes in this PR; the diff contains specific updates such as preserving StacTextStyle JSON behavior, adding StacGradient.linear/radial/sweep constructors, and multiple parser/serializer changes that the title does not surface. Because it does not highlight the main modifications or the affected subsystems, the title is inconclusive for reviewers scanning history. Please rename the PR to a concise, descriptive title that highlights the primary changes; for example, "Preserve StacTextStyle JSON format and add Flutter-like StacGradient constructors" or "Fix StacTextStyle JSON regression; add StacGradient constructors." If the intent is mainly bug fixes, explicitly name the subsystem and bug (e.g., "Fix StacTextStyle JSON regression") so reviewers can quickly understand the focus.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

Comment @coderabbitai help to get the list of available commands and usage tips.

@divyanshub024
Copy link
Member

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 20, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
examples/movie_app/lib/main.dart (2)

6-7: Hard-coded API token committed to source. Remove immediately.

Do not ship secrets in code; this can be abused even in examples.

Apply this diff to read from a build-time env and guard header injection:

-final token =
-    "eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiI5YzNjN2I1OGQ5NjU5NzUwMmNjODAxNWRkZjNjNTY1MyIsIm5iZiI6MTc0NDY1NDUzNi4zMjgsInN1YiI6IjY3ZmQ1MGM4N2MyOWFlNWJjM2Q5NjEzNiIsInNjb3BlcyI6WyJhcGlfcmVhZCJdLCJ2ZXJzaW9uIjoxfQ.oZWfMnM-eiPjHvlvjLbrZeQXCfm2lvgGiNx8xDovzW8";
+// Supply via: flutter run --dart-define=TMDB_TOKEN=...
+const token = String.fromEnvironment('TMDB_TOKEN', defaultValue: '');
-        options.headers['Authorization'] = 'Bearer $token';
+        if (token.isNotEmpty) {
+          options.headers['Authorization'] = 'Bearer $token';
+        }

56-57: Invalid hex color literals in light theme.

These are malformed lengths and will fail parsing.

Apply this diff:

-    "outline": "#080110810",
-    "onOutline": "#120110810",
+    "outline": "#08010810",
+    "onOutline": "#12010810",

Rationale: keep AARRGGBB with RR=01, GG=08, BB=10 to match nearby usage.

examples/movie_app/assets/jsons/screens/onboarding_screen.json (1)

59-63: Span key mismatch — many JSON spans still use "data" instead of "text"; migrate assets or update parser.

StacTextSpan expects "text" — spans with only "data" will be dropped. Occurrences found in:

  • examples/movie_app/assets/jsons/screens/{detail_screen.json, home_screen.json, onboarding_screen.json} (light_theme.json is invalid)
  • many files under examples/stac_gallery/assets/json/ (e.g. align_example.json, aspect_ratio_example.json, auto_complete_example.json, backdrop_filter_example.json, bottom_nav_bar_example.json, bottom_sheet_example.json, card_example.json, carousel_view_example.json, center_example.json, chip_example.json, ... , app_bar_example.json — see verification script output for full list and exact JSON pointers)

Action: replace "data" → "text" in these JSON assets OR make the deserializer accept "data" as a fallback; re-run the verification script to confirm all occurrences are resolved.

🧹 Nitpick comments (13)
examples/movie_app/lib/main.dart (1)

97-109: DRY the repeated shape map.

Extract a shared const to avoid duplication and drift.

Apply this diff within the selected lines:

-    "shape": {"type": "roundedRectangleBorder", "borderRadius": 8},
+    "shape": _rrect8,
-    "shape": {"type": "roundedRectangleBorder", "borderRadius": 8},
+    "shape": _rrect8,

Add this above darkThemeJson:

const _rrect8 = {"type": "roundedRectangleBorder", "borderRadius": 8};
packages/stac/lib/src/parsers/painting/stac_text_style_parser.dart (1)

10-43: Optional: collapse theme mapping to a lookup to reduce boilerplate.

A small map or helper function can replace the large switch without changing behavior.

Example helper:

TextStyle? _pickTheme(TextTheme t, StacMaterialTextStyle s) => <StacMaterialTextStyle, TextStyle?>{
  StacMaterialTextStyle.displayLarge:  t.displayLarge,
  StacMaterialTextStyle.displayMedium: t.displayMedium,
  // ...rest...
}[s];
packages/stac_core/lib/foundation/effects/stac_gradient/stac_gradient.dart (5)

93-106: Add basic asserts for linear gradient inputs.

Catch common JSON/config mistakes early (length/stops).

   const StacGradient.linear({
     required this.colors,
     this.stops,
     this.begin,
     this.end,
     this.tileMode,
-  }) : gradientType = StacGradientType.linear,
+  }) : assert(colors.length >= 2, 'colors must have at least two entries'),
+       assert(stops == null || stops.length == colors.length,
+           'stops length must match colors length'),
+       gradientType = StacGradientType.linear,
        center = null,
        focal = null,
        focalRadius = null,
        radius = null,
        startAngle = null,
        endAngle = null;

118-131: Add validation for radial parameters.

Radius/focalRadius bounds and stops length help avoid runtime surprises.

   const StacGradient.radial({
     required this.colors,
     this.stops,
     this.center,
     this.focal,
     this.focalRadius,
     this.radius,
     this.tileMode,
-  }) : gradientType = StacGradientType.radial,
+  }) : assert(colors.length >= 2, 'colors must have at least two entries'),
+       assert(stops == null || stops.length == colors.length,
+           'stops length must match colors length'),
+       assert(radius == null || radius > 0, 'radius must be > 0'),
+       assert(focalRadius == null || focalRadius >= 0,
+           'focalRadius must be >= 0'),
+       gradientType = StacGradientType.radial,
        begin = null,
        end = null,
        startAngle = null,
        endAngle = null;

144-157: Add basic angle assertions for sweep.

Ensure ordering and stops integrity.

   const StacGradient.sweep({
     required this.colors,
     this.stops,
     this.center,
     this.startAngle,
     this.endAngle,
     this.tileMode,
-  }) : gradientType = StacGradientType.sweep,
+  }) : assert(colors.length >= 2, 'colors must have at least two entries'),
+       assert(stops == null || stops.length == colors.length,
+           'stops length must match colors length'),
+       assert(
+         startAngle == null || endAngle == null || endAngle >= startAngle,
+         'endAngle must be >= startAngle',
+       ),
+       gradientType = StacGradientType.sweep,
        begin = null,
        end = null,
        focal = null,
        focalRadius = null,
        radius = null;

216-218: Alias pattern is fine; consider top‑level wrappers if you want parameter docs/completions.

The const tear‑off works, but a named top‑level function can expose parameter docs without lints. Optional.

// Optional alternative:
// StacGradient StacLinearGradient({...}) => StacGradient.linear(...);

202-205: Docs: note angles are radians (already done for sweep) and default tileMode equals Flutter’s default (clamp).

Minor clarity tweak to reduce ambiguity in JSON authorship.

packages/stac_core/lib/core/converters/stac_text_style_converter.dart (1)

22-35: String handling is strict; optionally allow case-insensitive matches.

A small guard reduces authoring errors (“BodyMedium” vs “bodyMedium”).

-    if (json is String) {
+    if (json is String) {
+      final key = json.trim();
       for (final value in StacMaterialTextStyle.values) {
-        if (value.name == json) {
+        if (value.name == key) {
           return StacTextStyle.fromTheme(textTheme: value);
         }
       }
packages/stac/lib/src/parsers/widgets/stac_text/stac_text_parser.dart (1)

41-41: Minor: avoid temp allocation for empty children.

Use a const empty list to skip a runtime allocation when children is null.

-    var children = model.children ?? [];
+    final children = model.children ?? const <StacTextSpan>[];

Also applies to: 44-47

packages/stac_core/lib/foundation/text/stac_text_style/stac_text_style.dart (4)

257-261: Docs: JSON example uses style key; should be textTheme.

Update the example to match the actual schema.

-  /// ```json
-  /// { "type": "theme", "style": "titleMedium" }
-  /// ```
+  /// ```json
+  /// { "type": "theme", "textTheme": "titleMedium" }
+  /// ```

261-278: fromJson: make type parsing robust and explicit.

Cast to String?, normalize case, and avoid dynamic comparisons.

-  factory StacTextStyle.fromJson(Map<String, dynamic> json) {
-    final typeString = json['type'];
+  factory StacTextStyle.fromJson(Map<String, dynamic> json) {
+    final typeString = (json['type'] as String?)?.toLowerCase();
     StacTextStyleType parsedType = StacTextStyleType.custom;
     for (final value in StacTextStyleType.values) {
-      if (value.name == typeString) {
+      if (value.name == typeString) {
         parsedType = value;
         break;
       }
     }
     switch (parsedType) {
       case StacTextStyleType.custom:
         return StacCustomTextStyle.fromJson(json);
       case StacTextStyleType.theme:
         return StacThemeTextStyle.fromJson(json);
     }
   }

491-503: Make StacThemeTextStyle immutable/const; return consts from getters.

These instances are value objects; const reduces allocations.

-class StacThemeTextStyle extends StacTextStyle {
+class StacThemeTextStyle extends StacTextStyle {
   ...
-  StacThemeTextStyle({required this.textTheme})
+  const StacThemeTextStyle({required this.textTheme})
       : super._(type: StacTextStyleType.theme);

And in StacThemeTextStyles getters:

-  StacThemeTextStyle get bodyMedium =>
-      StacThemeTextStyle(textTheme: StacMaterialTextStyle.bodyMedium);
+  StacThemeTextStyle get bodyMedium =>
+      const StacThemeTextStyle(textTheme: StacMaterialTextStyle.bodyMedium);

(Apply similarly to all getters.)


300-305: Optional: omit nulls in custom style JSON to reduce noise.

If compatibility requires fewer nulls, annotate with includeIfNull: false.

-@JsonSerializable()
+@JsonSerializable(includeIfNull: false)
 class StacCustomTextStyle extends StacTextStyle {

Regenerate and verify downstream snapshots.

Also applies to: 426-429

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e7eabc4 and c0075ab.

📒 Files selected for processing (13)
  • examples/movie_app/assets/jsons/screens/onboarding_screen.json (2 hunks)
  • examples/movie_app/lib/main.dart (1 hunks)
  • packages/stac/lib/src/parsers/painting/stac_text_style_parser.dart (1 hunks)
  • packages/stac/lib/src/parsers/widgets/stac_text/stac_text_parser.dart (4 hunks)
  • packages/stac_core/lib/core/converters/stac_text_style_converter.dart (1 hunks)
  • packages/stac_core/lib/foundation/effects/stac_gradient/stac_gradient.dart (3 hunks)
  • packages/stac_core/lib/foundation/text/stac_text_span/stac_text_span.dart (2 hunks)
  • packages/stac_core/lib/foundation/text/stac_text_span/stac_text_span.g.dart (2 hunks)
  • packages/stac_core/lib/foundation/text/stac_text_style/stac_text_style.dart (2 hunks)
  • packages/stac_core/lib/foundation/text/stac_text_style/stac_text_style.g.dart (3 hunks)
  • packages/stac_core/lib/widgets/text/stac_text.dart (2 hunks)
  • packages/stac_core/lib/widgets/text/stac_text.g.dart (2 hunks)
  • packages/stac_core/pubspec.yaml (1 hunks)
🔇 Additional comments (16)
examples/movie_app/lib/main.dart (2)

101-101: Shape discriminator added — confirm DSL value and fallback.

Ensure the parser expects the exact string "roundedRectangleBorder" (case/camelCase) and that older JSON without "type" still defaults correctly to a rounded rectangle.


108-108: Same check for outlined button shape.

Confirm the accepted enum/string for type and backward-compat defaulting behavior mirrors filled buttons.

packages/stac/lib/src/parsers/painting/stac_text_style_parser.dart (1)

7-8: Behavior change: parse() is now nullable — verify all call sites.

Returning TextStyle? can propagate nulls from Theme.of(context).textTheme.*. Please audit callers to ensure they handle null (e.g., defaulting to DefaultTextStyle.of(context).style or a safe fallback) and update any non-null expectations in parsing/renderers.

Also applies to: 67-68

examples/movie_app/assets/jsons/screens/onboarding_screen.json (1)

25-38: Gradient JSON now includes gradientType — looks correct.

Matches the new StacGradient constructors and enum. No issues.

packages/stac_core/lib/foundation/text/stac_text_span/stac_text_span.g.dart (1)

11-12: Converter usage wired correctly in generated code.

style now (de)serializes via StacTextStyleConverter. LGTM.

Also applies to: 23-24

packages/stac_core/lib/foundation/text/stac_text_span/stac_text_span.dart (1)

2-2: Good move to annotate style with the converter.

Keeps JSON flexible for theme/custom styles.

Also applies to: 47-48

packages/stac_core/lib/widgets/text/stac_text.dart (3)

60-64: Children is now nullable — ensure (de)serializers and renderers handle null as empty list.

Confirm stac_text.g.dart maps null to [] and widgets don’t assume non-null.


131-145: type getter and (de)serialization API: LGTM.

Public contract is clear and consistent with surrounding widgets.


74-84: Remove the incorrect converter annotation on copyWithStyle — generator already handles StacCustomTextStyle

stac_text.g.dart deserializes copyWithStyle with StacCustomTextStyle.fromJson and serializes with instance.copyWithStyle?.toJson(), so the @StacTextStyleConverter() on the StacCustomTextStyle? field is mismatched/unused; remove it or replace with a dedicated StacCustomTextStyleConverter only if you add that converter, and tighten the docs to “custom style object only”.
Location: packages/stac_core/lib/widgets/text/stac_text.dart (copyWithStyle field)

Likely an incorrect or invalid review comment.

packages/stac_core/pubspec.yaml (1)

18-18: New dependency added — run pub resolution and verify CI caching

packages/stac_core/pubspec.yaml (line 18) adds stac_logger: ^1.1.0; rg shows many imports of package:stac_logger across packages/stac* and packages/stac_logger/*. Run locally and in CI: dart pub get && dart pub outdated to detect transitive/version conflicts and update CI cache key so the new package is picked up.

packages/stac/lib/src/parsers/widgets/stac_text/stac_text_parser.dart (2)

7-9: Good import hygiene.

Switching to explicit stac_core imports tightens API exposure and reduces accidental dependencies.


25-25: Style override merge looks correct; verify intended inheritance.

base (theme/custom) is parsed, then selectively overridden via copyWith. This preserves null-as-“keep base” semantics. Please double‑check that allowing override.inherit to flip inheritance on the root TextStyle is desired since it can prevent DefaultTextStyle inheritance.

Also applies to: 57-89

packages/stac_core/lib/foundation/text/stac_text_style/stac_text_style.g.dart (2)

44-48: JSON shape check: type emitted for custom styles.

To “maintain existing JSON format,” confirm that adding "type": "custom" in StacCustomTextStyle.toJson is acceptable. If not, route serialization via a converter that omits type for custom or set includeToJson=false for type on this path.


119-129: Theme style (de)serialization LGTM.

Discriminator + enum mapping is consistent and unambiguous.

packages/stac_core/lib/widgets/text/stac_text.g.dart (2)

11-14: Null children and style converter usage.

  • children now nullable on (de)serialization; parser already guards with ?? []. Ensure producers won’t rely on an empty [] being emitted.
  • Using StacTextStyleConverter for style meets the backward‑compat goal.

If you need to avoid emitting "children": null/"style": null, annotate StacText with @JsonSerializable(includeIfNull: false) and regenerate.

Also applies to: 37-41


15-19: copyWithStyle serialization may introduce type into output.

Because copyWithStyle calls StacCustomTextStyle.toJson, "type": "custom" will be written. Confirm that this is acceptable for the new field; otherwise add a dedicated converter to omit type for custom.

Also applies to: 41-42

Comment on lines 17 to 48
StacTextStyle? fromJson(dynamic json) {
if (json == null) return null;

if (json is StacTextStyle) return json;

if (json is String) {
for (final value in StacMaterialTextStyle.values) {
if (value.name == json) {
return StacTextStyle.fromTheme(textTheme: value);
}
}

Log.w(
'StacTextStyleConverter: Invalid theme style string "$json". '
'Valid values are: ${StacMaterialTextStyle.values.map((e) => e.name).join(', ')}. '
'Returning null.',
);
return null;
}

if (json is Map<String, dynamic>) {
try {
if (json.containsKey('type')) {
return StacTextStyle.fromJson(json);
} else {
return StacCustomTextStyle.fromJson(json);
}
} catch (e) {
Log.w(
'StacTextStyleConverter: Failed to parse style object: $json. '
'Error: $e. Returning null.',
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we please replace StacTextStyleConverter logic with StacTextStyle.fromJson. This will avoid the need to specify the StacTextStyleConverter explicitly


final overrideParsed = override.parse(context);
if (overrideParsed == null) return baseStyle;
if (baseStyle == null) return overrideParsed;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the baseStyle is null, then should we even return the overrideParsed? Shouldn't we just return null??

@divyanshub024 divyanshub024 merged commit b2b66b0 into dv/stac-export Sep 21, 2025
5 checks passed
@divyanshub024 divyanshub024 deleted the mn/stac-text-style-changes branch September 21, 2025 16:49
@coderabbitai coderabbitai bot mentioned this pull request Sep 22, 2025
7 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants