Skip to content

Migrate from codelessly_json_annotation to json_annotation - #34

Merged
rayliverified merged 17 commits into
masterfrom
claude/hopeful-brown-c8o8x7
Oct 13, 2026
Merged

rayliverified merged 17 commits into
masterfrom
claude/hopeful-brown-c8o8x7

Conversation

@rayliverified

Copy link
Copy Markdown
Contributor

Summary

This PR migrates the codelessly_api package from the forked codelessly_json_annotation package to the standard json_annotation package. It also introduces a custom JSON defaults generator to handle omitting default values from serialized JSON.

Key Changes

  • Dependency Migration: Replaced all imports of codelessly_json_annotation with json_annotation across the codebase
  • JSON Defaults Generator: Introduced a new custom builder (json_defaults_builder) that generates _$<ClassName>OmitDefaults functions to remove default values from JSON serialization, reducing payload size
  • Generated Code Updates: Updated all .g.dart files to use the new JsonDefaultsGenerator instead of JsonSerializableGenerator
  • Code Formatting: Applied consistent formatting to several source files (e.g., button_node.dart, dropdown_node.dart)
  • Enum Trailing Commas: Added trailing commas to enum definitions for consistency (e.g., EmbeddedVideoSource, TextAlignVerticalEnum)
  • Mixin Updates: Changed EquatableMixin to Equatable in paint.dart and node_box.dart
  • Build Configuration: Updated build.yaml to use json_serializable builder instead of codelessly_json_serializable
  • CI/CD: Added GitHub Actions workflow for continuous integration
  • Documentation: Updated CHANGELOG.md with version 5.0.0 breaking changes and added .pubignore file
  • Tests: Added golden tests for node JSON serialization and properties validation

Implementation Details

  • The new json_defaults_builder tool generates helper functions that intelligently remove fields with default values before JSON serialization
  • Default value detection uses isJsonDefault() helper function with type-specific comparisons
  • Special handling for constraints with excludeConstraintsIf() function
  • Minimum Dart version requirement increased to 3.13
  • All generated code maintains backward compatibility with existing JSON deserialization

https://claude.ai/code/session_01A67XoQYsLVvoMtiKcXXUxY

claude added 17 commits October 13, 2026 01:39
Replace codelessly_json_annotation / codelessly_json_serializable with
json_annotation 4.12 and json_serializable 6.14, which build on Dart 3.13.

The fork omitted fields equal to their constructor default from toJson.
Keep that output identical with a small dev-only builder in
tool/json_defaults_builder that generates _$XOmitDefaults(instance, json)
per class; toJson now calls _$XOmitDefaults(this, _$XToJson(this)).
JsonKey.excludeIf becomes @JsonOmitIf, the fork's DateTime converter is
vendored in converters.dart, and useDynamics is dropped.

Golden tests pin toJson output and round-tripping against JSON produced
by the 4.4.0 fork-based build.

Also bumps the SDK constraint to ^3.13.0, equatable 3, lints 6 and
other dependencies to their latest versions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A67XoQYsLVvoMtiKcXXUxY
- Ignore must_be_immutable: nodes are mutable by design and Equatable 3
  is @immutable.
- Fix TypedValue.toEdgeInsetsModel, whose type-literal patterns compared
  against the Type objects and never matched.
- Drop @OverRide on factories, a dead null-aware fallback, and the
  deprecated Matrix4.translate; use initializing formals and document
  the remaining public members.
- Reformat with the Dart 3.13 formatter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A67XoQYsLVvoMtiKcXXUxY
- ListTileNode.empty/fromProperties and ExpansionTileNode.empty left
  late fields unset and threw on first access. ExpansionTileNode.empty
  also reused the list tile id and name.
- FloatingActionButtonNode.empty and EmbeddedVideoNode.empty used the
  switch and slider preview sizes.
- Remove the blend and value constructor parameters that
  LoadingIndicatorNode, ProgressBarNode and DividerNode accepted and
  discarded.
- copyWith dropped Divider thickness, Dropdown enabled/dense/expanded/
  autoFocus/enableFeedback, FAB location and M2 navigation bar notch
  settings.
- props omitted fields, so changed properties compared equal:
  ExpansionTile (all), grid delegate spacing, Dropdown, Divider, FAB,
  ListTile visibility flags, TabBar indicator shape, icon scale, the
  shared WebView settings, submit action service and Mailchimp fields,
  Vimeo metadata, condition group name and visual density type.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A67XoQYsLVvoMtiKcXXUxY
- TextAlignHorizontalEnum: start, end (RTL-aware TextAlign values).
- ButtonTypeEnum: filled, filledTonal (FilledButton).
- AutovalidateModeC: onUnfocus, onUserInteractionIfError.
- FABLocation: endContained.
- TextInputTypeEnum: webSearch, twitter.
- SliderTrackShapeEnum: gapped; SliderValueIndicatorShape: drop,
  roundedRectangle (Material 3 slider shapes).
- CShapeBorder: roundedSuperellipse (RoundedSuperellipseBorder).

Additions only, so existing JSON reads unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A67XoQYsLVvoMtiKcXXUxY
- InputDecorationModel.contentPadding, which copyWith already accepted
  and silently dropped.
- MultiSourceIconModel fill, weight, grade and opticalSize, the
  variable-font axes Material Symbols need.
- AppBarProperties foregroundColor and scrolledUnderElevation.
- TabBarProperties tabAlignment (new TabAlignmentC enum) and
  dividerHeight.

All are optional and null by default, so existing JSON is unchanged.
Also document the Flutter replacements for the deprecated scroll view
cacheExtent (scrollCacheExtent) and Radio.groupValue (RadioGroup).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A67XoQYsLVvoMtiKcXXUxY
TextFieldNode was the only custom node without a 'properties' field
accessor, and TextFieldProperties had no FieldsHolder at all. The M2
and M3 navigation bar properties only exposed the shared notch and
item fields, not their own colors, label styles, icon sizes,
elevation and layout options.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A67XoQYsLVvoMtiKcXXUxY
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A67XoQYsLVvoMtiKcXXUxY
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A67XoQYsLVvoMtiKcXXUxY
A text field node's padding is already rendered as the decoration's
content padding, so a separate field would conflict with it. Remove the
ignored copyWith parameter instead and document where the padding lives.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A67XoQYsLVvoMtiKcXXUxY
The SDK renders icons as SVGs and does not render Material Symbols yet,
so fill/weight/grade/opticalSize would be stored but never applied.
Add them together with Material Symbols rendering instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A67XoQYsLVvoMtiKcXXUxY
Stored JSON omits fields equal to their default, so changing a default
would silently restyle every saved design. Keep the old value as the
read default (@jsonkey(defaultValue: ...) for literals, the new
@JsonLegacyDefault plus readValue for objects) and let the defaults
builder omit fields only when they equal that old value. New nodes get
Material 3 values and write them explicitly.

Changed: Switch useMaterial3, button shape and preferred padding, FAB
shape/radius/elevations/icon spacing and extended size, list and
expansion tile padding, tab indicator size, and navigation bar
elevation.

The golden test now checks that 4.4.0 JSON re-serializes unchanged and
pins the output for new nodes in a second fixture.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A67XoQYsLVvoMtiKcXXUxY
Radio side/innerRadius/backgroundColor; Slider showValueIndicator,
secondaryTrackValue, secondaryActiveTrackColor and padding; ListTile
minTileHeight and titleAlignment; CircularProgressIndicator strokeAlign
and trackGap; ExpansionTile showTrailingIcon; Text softWrap. New enums
ShowValueIndicatorC and ListTileTitleAlignmentC. All optional with
Flutter's defaults, so existing JSON is unchanged.

Button minimumSize/fixedSize stay out: the node's box sizes the button.

Also run CI on pushes to every branch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A67XoQYsLVvoMtiKcXXUxY
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A67XoQYsLVvoMtiKcXXUxY
Document in the README which Flutter parameters are represented
elsewhere or cannot be JSON.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A67XoQYsLVvoMtiKcXXUxY
The SDK now renders Material Symbols from Google's prebuilt SVGs, whose
URLs encode weight, grade, fill and optical size, so fill, weight, grade
and opticalSize on MultiSourceIconModel have a renderer again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A67XoQYsLVvoMtiKcXXUxY
Layouts containing a placeholder node failed to load because
NodeJsonConverter had no deserializer for its type. A new test checks
that every node type declared in the package is registered.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A67XoQYsLVvoMtiKcXXUxY
@rayliverified
rayliverified merged commit 526d0a3 into master Oct 13, 2026
2 checks passed
rayliverified pushed a commit to Codelessly/CodelesslySDK that referenced this pull request Oct 13, 2026
The API changes are merged (Codelessly/CodelesslyAPI#34). Keep the git
override until codelessly_api 5.0.0 is published to pub.dev.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A67XoQYsLVvoMtiKcXXUxY
rayliverified added a commit that referenced this pull request Oct 13, 2026
Move off the forked JSON codegen to json_annotation/json_serializable with a small defaults builder that keeps stored JSON unchanged; mirror current Flutter widget parameters and enums; default new nodes to Material 3 while legacy JSON keeps its look; fix uninitialized nodes, lossy copyWith and incomplete equality; register PlaceholderNode; add CI and tests.

Claude-Session: https://claude.ai/code/session_01A67XoQYsLVvoMtiKcXXUxY
rayliverified added a commit that referenced this pull request Oct 13, 2026
Move off the forked JSON codegen to json_annotation/json_serializable with a small defaults builder that keeps stored JSON unchanged; mirror current Flutter widget parameters and enums; default new nodes to Material 3 while legacy JSON keeps its look; fix uninitialized nodes, lossy copyWith and incomplete equality; register PlaceholderNode; add CI and tests.
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.

2 participants