Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: CI

on:
push:
pull_request:
workflow_dispatch:

jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: dart-lang/setup-dart@v1
with:
sdk: 3.13.5
- run: dart pub get
- run: dart pub get --directory tool/json_defaults_builder
- name: Generated code is up to date
run: |
dart run build_runner build -d
git diff --exit-code -- '*.g.dart'
- run: dart format --set-exit-if-changed --output=none lib test tool
- run: dart analyze --fatal-infos
- run: dart test
- run: dart pub publish --dry-run
78 changes: 78 additions & 0 deletions .pubignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
tool/
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/

# IntelliJ related
*.iml
*.ipr
*.iws
.idea/

# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/

# Flutter/Dart/Pub related
**/doc/api/
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
build/

# Android related
**/android/**/gradle-wrapper.jar
**/android/.gradle
**/android/captures/
**/android/gradlew
**/android/gradlew.bat
**/android/local.properties
**/android/**/GeneratedPluginRegistrant.java

# iOS/XCode related
**/ios/**/*.mode1v3
**/ios/**/*.mode2v3
**/ios/**/*.moved-aside
**/ios/**/*.pbxuser
**/ios/**/*.perspectivev3
**/ios/**/*sync/
**/ios/**/.sconsign.dblite
**/ios/**/.tags*
**/ios/**/.vagrant/
**/ios/**/DerivedData/
**/ios/**/Icon?
**/ios/**/Pods/
**/ios/**/.symlinks/
**/ios/**/profile
**/ios/**/xcuserdata
**/ios/.generated/
**/ios/Flutter/App.framework
**/ios/Flutter/Flutter.framework
**/ios/Flutter/Flutter.podspec
**/ios/Flutter/Generated.xcconfig
**/ios/Flutter/app.flx
**/ios/Flutter/app.zip
**/ios/Flutter/flutter_assets/
**/ios/Flutter/flutter_export_environment.sh
**/ios/ServiceDefinitions.json
**/ios/Runner/GeneratedPluginRegistrant.*

# Exceptions to above rules.
!**/ios/**/default.mode1v3
!**/ios/**/default.mode2v3
!**/ios/**/default.pbxuser
!**/ios/**/default.perspectivev3

pubspec.lock
pubspec_overrides.yaml
81 changes: 81 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,84 @@
## 5.0.0

### Breaking changes

- Require Dart 3.13.
- Replace the forked `codelessly_json_annotation` and
`codelessly_json_serializable` with the standard `json_annotation` and
`json_serializable`. Custom nodes should import
`package:json_annotation/json_annotation.dart`. `DateTimeConverter` is
now exported by this package.
- Upgrade to equatable 3, which removes `EquatableMixin`; models mix in
`Equatable` instead.
- Remove the unused blend and `value` constructor parameters of
`LoadingIndicatorNode`, `ProgressBarNode` and `DividerNode`, which were
silently discarded.
- Remove the unused `automaticChevron` parameter of
`ExpansionTileProperties.copyWith`.

### JSON

- Serialized JSON is unchanged: fields that equal their defaults are still
omitted, now by a small build step in `tool/json_defaults_builder`.
Golden tests pin the output against 4.4.0.
- Cloud database query `whereFilters`/`orderByFilters` are omitted when
empty; they read back as empty lists.

### Flutter parity

- Mirror new Flutter values: `TextAlignHorizontalEnum.start`/`end`,
`ButtonTypeEnum.filled`/`filledTonal`, `FABLocation.endContained`,
`TextInputTypeEnum.webSearch`/`twitter`,
`AutovalidateModeC.onUnfocus`/`onUserInteractionIfError`,
`SliderTrackShapeEnum.gapped`, `SliderValueIndicatorShape.drop`/
`roundedRectangle` and `CShapeBorder.roundedSuperellipse`.
- Add Flutter parameters that were missing:
- `AppBarProperties.foregroundColor`, `scrolledUnderElevation`
- `TabBarProperties.tabAlignment` (new `TabAlignmentC`), `dividerHeight`
- `RadioProperties.side`, `innerRadius`, `backgroundColor`
- `SliderProperties.showValueIndicator` (new `ShowValueIndicatorC`),
`secondaryTrackValue`, `secondaryActiveTrackColor`, `padding`
- `ListTileProperties.minTileHeight`, `titleAlignment` (new
`ListTileTitleAlignmentC`)
- `MaterialLoadingIndicatorProperties.strokeAlign`, `trackGap`
- `ExpansionTileProperties.showTrailingIcon`, `shape`, `collapsedShape`,
`cornerRadius`
- `TextMixin.softWrap`, `textScaleFactor`
- `MultiSourceIconModel.fill`, `weight`, `grade`, `opticalSize` (the
Material Symbols variable-font axes)
- `PageViewProperties.allowImplicitScrolling`
- Document the Flutter replacements for deprecated `cacheExtent`
(`scrollCacheExtent`) and `Radio.groupValue` (`RadioGroup`).
- New nodes use Material 3 defaults: switches use Material 3, buttons are
stadium-shaped with 24 px horizontal padding, FABs are rounded rectangles
(radius 16) with Material 3 elevations, a 56 px extended height and 8 px
icon spacing, list and expansion tiles use 16/24 px content padding, tab
indicators size to the label, and navigation bars use elevation 3 (M3)
and 8 (M2).
- Designs saved before 5.0.0 keep their look: a missing key still reads as
the old default, and re-saving them writes the same JSON. The new
`JsonLegacyDefault` annotation supports this for non-literal defaults.

### Fixes

- Register `PlaceholderNode` with `NodeJsonConverter`; layouts containing
one failed to deserialize.
- `ListTileNode.empty`/`fromProperties` and `ExpansionTileNode.empty`
no longer leave late fields uninitialized.
- `FloatingActionButtonNode.empty` and `EmbeddedVideoNode.empty` use their
own sizes.
- `copyWith` keeps Divider `thickness`, Dropdown `enabled`/`dense`/
`expanded`/`autoFocus`/`enableFeedback`, FAB `location`, M2 navigation
bar notch settings.
- Remove the `contentPadding` parameter of `InputDecorationModel.copyWith`,
which was ignored; a text field's content padding is its node padding.
- Equality includes previously ignored fields of ExpansionTile, grid
delegates, Dropdown, Divider, FAB, ListTile, TabBar, icons, web views,
submit actions, Vimeo videos, condition groups and visual density.
- `TypedValue.toEdgeInsetsModel` converts numbers and lists again.
- Add field access for `TextFieldProperties` and the navigation bar
properties.

## 4.4.0

- Add CornerRadius typedValue.
Expand Down
23 changes: 21 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ This is how you can create a custom `BaseNode`:

```dart
import 'package:codelessly_api/codelessly_api.dart';
import 'package:codelessly_json_annotation/codelessly_json_annotation.dart';
import 'package:json_annotation/json_annotation.dart';

part 'custom_node.g.dart';

Expand All @@ -44,7 +44,7 @@ class CustomNode extends BaseNode {
@override
final String type = 'custom_node';

MyCoolNode({
CustomNode({
required super.id,
required super.name,
required super.basicBoxLocal,
Expand All @@ -57,6 +57,9 @@ class CustomNode extends BaseNode {
}
```

Generate the serialization code with `dart run build_runner build`, using
[json_serializable](https://pub.dev/packages/json_serializable).

All nodes must extend `BaseNode`. Please refer to the documentation inside `BaseNode` for more information.

Then, register your node with the `NodeJsonConverter` so that it can be properly deserialized from json. The
Expand Down Expand Up @@ -113,6 +116,22 @@ or image texture.
opacity (`opacity`), among others. Depending on the type of paint, it might have properties like color (`color`),
gradient transform (`gradientTransform`), gradient stops (`gradientStops`), or image transform (`imageTransform`).

### Flutter parity

Models track the Flutter release this version supports (3.47). A Flutter
parameter is left out when it cannot be data or is already expressed
elsewhere:

| Flutter parameter | Represented by |
|---|---|
| Size and padding parameters such as `ButtonStyle.minimumSize`/`fixedSize`, `InputDecoration.contentPadding` and `TabBar.padding` | The node's own box and `padding` |
| `ScrollView.clipBehavior` and similar clip parameters | `ClipMixin.clipsContent` |
| Callbacks and widgets, such as `itemExtentBuilder` and `prototypeItem` | Not representable as JSON; use `itemExtent` |

Defaults follow Material 3. Where a default changed from an earlier
version, the old value still applies to JSON that omits the key (see
`JsonLegacyDefault`), so saved designs keep their look.

## Contributing

Contributions are welcome! Please open an issue to start a discussion.
Expand Down
4 changes: 4 additions & 0 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ analyzer:
missing_required_param: error
missing_return: error
todo: ignore
# Nodes and their properties are mutable by design: the editor updates
# them in place. Equatable 3 marks itself @immutable, which would flag
# every one of them.
must_be_immutable: ignore

linter:
rules:
Expand Down
11 changes: 5 additions & 6 deletions build.yaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
targets:
$default:
builders:
codelessly_json_serializable:
json_serializable:
options:
# The other properties are the same as default (https://pub.dev/packages/json_serializable#build-configuration).
# explicit_to_json must be true for nested properties to work (like a Paint inside a Frame, toJson must be called in both)
# explicit_to_json must be true for nested models (like a Paint inside a Frame) to serialize.
explicit_to_json: true
# include_if_null should be false to avoid sending null properties to Firebase.
# Null values are not written, to avoid sending null properties to Firebase.
include_if_null: false
any_map: true # The squadron library for web requires dynamic maps.
serialize_default_values: false
# The squadron library for web requires dynamic maps.
any_map: true
2 changes: 1 addition & 1 deletion example/example.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

```dart
import 'package:codelessly_api/codelessly_api.dart';
import 'package:codelessly_json_annotation/codelessly_json_annotation.dart';
import 'package:json_annotation/json_annotation.dart';

part 'custom_node.g.dart';

Expand Down
1 change: 1 addition & 0 deletions lib/codelessly_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export 'src/api/converters.dart';
export 'src/api/extensions.dart';
export 'src/api/field_access.dart';
export 'src/api/generate_id.dart';
export 'src/api/json_defaults.dart';
export 'src/api/math_helper.dart';
export 'src/api/mixins.dart';
export 'src/api/models/models.dart';
Expand Down
Loading
Loading