diff --git a/.fvmrc b/.fvmrc index a6427fd..c300356 100644 --- a/.fvmrc +++ b/.fvmrc @@ -1,4 +1,3 @@ { - "flutter": "stable", - "flavors": {} + "flutter": "stable" } \ No newline at end of file diff --git a/.gitignore b/.gitignore index e26e637..2d7bde6 100644 --- a/.gitignore +++ b/.gitignore @@ -27,12 +27,7 @@ migrate_working_dir/ # Ignoring native folders of the example as they can be re-generated easily using: # flutter create --platforms=android,ios,web,windows,macos . -**/example/android/ -**/example/ios/ -**/example/web/ -**/example/windows/ -**/example/macos/ -**/example/linux/ + # Flutter/Dart/Pub related **/doc/api/ diff --git a/.vscode/settings.json b/.vscode/settings.json index a4b2e23..9247999 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,5 +7,25 @@ "search.exclude": { "**/.fvm/versions": true, "**/.fvm/flutter_sdk": true - } + }, + "workbench.colorCustomizations": { + "activityBar.activeBackground": "#2f7c47", + "activityBar.background": "#2f7c47", + "activityBar.foreground": "#e7e7e7", + "activityBar.inactiveForeground": "#e7e7e799", + "activityBarBadge.background": "#422c74", + "activityBarBadge.foreground": "#e7e7e7", + "commandCenter.border": "#e7e7e799", + "sash.hoverBorder": "#2f7c47", + "statusBar.background": "#215732", + "statusBar.foreground": "#e7e7e7", + "statusBarItem.hoverBackground": "#2f7c47", + "statusBarItem.remoteBackground": "#215732", + "statusBarItem.remoteForeground": "#e7e7e7", + "titleBar.activeBackground": "#215732", + "titleBar.activeForeground": "#e7e7e7", + "titleBar.inactiveBackground": "#21573299", + "titleBar.inactiveForeground": "#e7e7e799" + }, + "peacock.color": "#215732" } \ No newline at end of file diff --git a/analysis_options.yaml b/analysis_options.yaml index c2bb38b..b1d3be9 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -8,9 +8,6 @@ analyzer: plugins: - custom_lint exclude: - - '**.freezed.dart' - - '**.g.dart' - - '**.gr.dart' - '**.mapper.dart' - '**/generated_plugin_registrant.dart' linter: diff --git a/build.yaml b/build.yaml index 1a94e2a..07b0827 100644 --- a/build.yaml +++ b/build.yaml @@ -3,7 +3,20 @@ targets: builders: dart_mappable_builder: generate_for: - - lib/**/*.dart + - lib/**/*_model.dart + mix_generator|spec: + generate_for: + - lib/**/*_spec.dart + mix_generator|dto: + generate_for: + - lib/**/*_spec.dart + mix_generator|enum_utility: + generate_for: + - lib/**/*_spec.dart + mix_generator|class_utility: + generate_for: + - lib/**/*_spec.dart + global_options: dart_mappable_builder: options: diff --git a/example/lib/src/style.dart b/example/lib/src/style.dart index ae3f43b..a1066fd 100644 --- a/example/lib/src/style.dart +++ b/example/lib/src/style.dart @@ -1,35 +1,51 @@ import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; +import 'package:superdeck/styles/style_util.dart'; import 'package:superdeck/superdeck.dart'; +final _util = SlideSpecUtility.self; +final _h1 = _util.h1; +final _h2 = _util.h2; +final _h3 = _util.h3; + +final _h6 = _util.h6; + +final _paragraph = _util.paragraph; + +final _code = _util.code; +final _blockquote = _util.blockquote; + +final _outerContainer = _util.outerContainer; +final _contentContainer = _util.contentContainer; + +final _textStyle = _util.textStyle; +final _innerContainer = _util.innerContainer; + VariantAttribute get radStyle { return const SlideVariant('rad')( - $deck.h1.textStyle.as(GoogleFonts.poppins()), - $deck.h1.textStyle.fontSize(140), - $deck.code.decoration.border.all( - color: Colors.red, - width: 3, + _h1.textStyle.as(GoogleFonts.poppins()), + _h1.textStyle.fontSize(140), + _code.decoration.border.all( + color: Colors.white, + width: 1, ), - $deck.code.decoration( - color: Colors.black54, - ), - $deck.code.padding.all(40), - - $deck.outerContainer.margin.all(60), - - $deck.innerContainer.borderRadius(25), - $deck.innerContainer.shadow( + _code.decoration.color.black(), + _code.padding.all(40), + _outerContainer.margin.all(60), + _innerContainer.borderRadius(25), + _innerContainer.shadow( blurRadius: 0, spreadRadius: 10, color: Colors.red.withOpacity(1), ), - $deck.innerContainer.gradient.radial( + _innerContainer.gradient.radial( stops: [0.0, 1.0], radius: 0.7, colors: [Colors.purple, Colors.deepPurple], ), - - // Events + $on.focus( + _innerContainer.color.yellow(), + ), $on.hover.event((e) { if (e == null) return const Style.empty(); final position = e.position; @@ -37,23 +53,22 @@ VariantAttribute get radStyle { final dy = position.y * 10; return Style( - $deck.innerContainer.transform(_transformMatrix(position)), - $deck.innerContainer.shadow.offset(dx, dy), - $deck.innerContainer.gradient.radial( + _innerContainer.transform(_transformMatrix(position)), + _innerContainer.shadow.offset(dx, dy), + _innerContainer.gradient.radial( center: position, ), ); }), - ($on.press | $on.longPress)( - $deck.innerContainer.shadow( + _innerContainer.shadow( blurRadius: 5, spreadRadius: 1, offset: Offset.zero, color: Colors.purpleAccent, ), - $deck.innerContainer.border.all(color: Colors.white, width: 1), - $deck.innerContainer.gradient.radial + _innerContainer.border.all(color: Colors.white, width: 1), + _innerContainer.gradient.radial .colors([Colors.purpleAccent, Colors.purpleAccent]), ), ); @@ -61,17 +76,17 @@ VariantAttribute get radStyle { VariantAttribute get customStyle { return const SlideVariant('custom')( - $deck.textStyle.as(GoogleFonts.poppins()), - $deck.h1.textStyle.as(GoogleFonts.smooch()), - $deck.h1.textStyle.fontSize(200), - $deck.h1.textStyle.height(0), - $deck.h1.textStyle.shadow( + _textStyle.as(GoogleFonts.poppins()), + _h1.textStyle.as(GoogleFonts.smooch()), + _h1.textStyle.fontSize(200), + _h1.textStyle.height(0), + _h1.textStyle.shadow( color: Colors.deepOrange, blurRadius: 20, ), - $deck.h2.textStyle.fontSize(36), - $deck.contentContainer.borderRadius(25), - $deck.innerContainer.gradient.linear( + _h2.textStyle.fontSize(36), + _contentContainer.borderRadius(25), + _innerContainer.gradient.linear( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ @@ -79,20 +94,20 @@ VariantAttribute get customStyle { Colors.deepPurple.withOpacity(0.9), ], ), - $deck.contentContainer.padding.vertical(0), - $deck.outerContainer.padding(40), - $deck.outerContainer.gradient.linear( + _contentContainer.padding.vertical(0), + _outerContainer.padding(40), + _outerContainer.gradient.linear( colors: [ Colors.red, Colors.redAccent, ], ), - $deck.innerContainer.borderRadius(25), - $deck.innerContainer.border.all( + _innerContainer.borderRadius(25), + _innerContainer.border.all( color: Colors.deepOrange, width: 4, ), - $deck.innerContainer.shadow( + _innerContainer.shadow( color: Colors.black.withOpacity(0.4), blurRadius: 20, spreadRadius: 5, @@ -102,9 +117,9 @@ VariantAttribute get customStyle { VariantAttribute get coverStyle { return const SlideVariant('cover')( - $deck.h1.textStyle.as(GoogleFonts.poppins()), - $deck.h1.textStyle.fontSize(100), - $deck.contentContainer.gradient.linear( + _h1.textStyle.as(GoogleFonts.poppins()), + _h1.textStyle.fontSize(100), + _contentContainer.gradient.linear( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ @@ -117,15 +132,15 @@ VariantAttribute get coverStyle { VariantAttribute get announcementStyle { return const SlideVariant('announcement')( - $deck.textStyle.height(0.6), - $deck.h1.textStyle.fontSize(140), - $deck.h1.textStyle.bold(), - $deck.h1.textStyle.color(Colors.yellow), - $deck.h2.textStyle.fontSize(140), - $deck.h3.textStyle.fontSize(60), - $deck.h3.textStyle.color(Colors.white), - $deck.h3.textStyle.fontWeight(FontWeight.w100), - $deck.contentContainer.gradient.linear( + _textStyle.height(0.6), + _h1.textStyle.fontSize(140), + _h1.textStyle.bold(), + _h1.textStyle.color(Colors.yellow), + _h2.textStyle.fontSize(140), + _h3.textStyle.fontSize(60), + _h3.textStyle.color(Colors.white), + _h3.textStyle.fontWeight(FontWeight.w100), + _contentContainer.gradient.linear( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ @@ -138,20 +153,20 @@ VariantAttribute get announcementStyle { VariantAttribute get quoteStyle { return const SlideVariant('quote')( - $deck.blockquote.textStyle.as(GoogleFonts.notoSerif()), - $deck.blockquote.decoration.border.left( + _blockquote.textStyle.as(GoogleFonts.notoSerif()), + _blockquote.decoration.border.left( width: 4, color: Colors.red, ), - $deck.paragraph.textStyle.fontSize(32), - $deck.h6.textStyle.as(GoogleFonts.notoSerif()), - $deck.h6.textStyle.fontSize(20), + _paragraph.textStyle.fontSize(32), + _h6.textStyle.as(GoogleFonts.notoSerif()), + _h6.textStyle.fontSize(20), ); } VariantAttribute get showSectionsStyle { return const SlideVariant('show_sections')( - $deck.contentContainer.border.all( + _contentContainer.border.all( color: Colors.blue, width: 2, ), @@ -160,14 +175,14 @@ VariantAttribute get showSectionsStyle { Style get style { return Style( - $deck.textStyle.as(GoogleFonts.poppins()), + _textStyle.as(GoogleFonts.poppins()), customStyle, quoteStyle, showSectionsStyle, coverStyle, announcementStyle, radStyle, - ); + ).animate(); } Matrix4 _transformMatrix(Alignment alignment) { diff --git a/example/lib/src/widget/mix_demo.dart b/example/lib/src/widget/mix_demo.dart index efca230..f13fcb2 100644 --- a/example/lib/src/widget/mix_demo.dart +++ b/example/lib/src/widget/mix_demo.dart @@ -1,7 +1,7 @@ import 'dart:math' as math; import 'package:flutter/material.dart'; -import 'package:superdeck/schema/schema.dart'; +import 'package:superdeck/schema/schema_model.dart'; import 'package:superdeck/superdeck.dart'; const purpleAccent = Color.fromARGB(255, 95, 44, 188); @@ -51,6 +51,10 @@ Style get _style => Style( ); }), + $on.hover( + $box.color.black(), + ), + ($on.press | $on.longPress)( $box.shadow( blurRadius: 5, @@ -110,8 +114,7 @@ class MixExample extends ExampleWidget { Widget build(ExampleOptions args) { return Builder(builder: (context) { return Center( - child: PressableBox( - onPress: () {}, + child: Box( style: Style( _style(), $box.height(args.height), diff --git a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..a2ec33f --- /dev/null +++ b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_16.png", + "scale" : "1x" + }, + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "2x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "1x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_64.png", + "scale" : "2x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_128.png", + "scale" : "1x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "2x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "1x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "2x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_1024.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png new file mode 100644 index 0000000..82b6f9d Binary files /dev/null and b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png differ diff --git a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png new file mode 100644 index 0000000..13b35eb Binary files /dev/null and b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png differ diff --git a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png new file mode 100644 index 0000000..0a3f5fa Binary files /dev/null and b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png differ diff --git a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png new file mode 100644 index 0000000..bdb5722 Binary files /dev/null and b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png differ diff --git a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png new file mode 100644 index 0000000..f083318 Binary files /dev/null and b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png differ diff --git a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png new file mode 100644 index 0000000..326c0e7 Binary files /dev/null and b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png differ diff --git a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png new file mode 100644 index 0000000..2f1632c Binary files /dev/null and b/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png differ diff --git a/example/pubspec.lock b/example/pubspec.lock index 32095c5..c6061cd 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -1,6 +1,22 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + sha256: "0b2f2bd91ba804e53a61d757b986f89f1f9eaed5b11e4b2f5a2468d86d6c9fc7" + url: "https://pub.dev" + source: hosted + version: "67.0.0" + analyzer: + dependency: transitive + description: + name: analyzer + sha256: "37577842a27e4338429a1cbc32679d508836510b056f1eedf0c8d20e39c1383d" + url: "https://pub.dev" + source: hosted + version: "6.4.1" animate_do: dependency: transitive description: @@ -57,6 +73,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.1" + build: + dependency: transitive + description: + name: build + sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + build_config: + dependency: transitive + description: + name: build_config + sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 + url: "https://pub.dev" + source: hosted + version: "1.1.1" cached_network_image: dependency: transitive description: @@ -97,6 +129,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.1" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff + url: "https://pub.dev" + source: hosted + version: "2.0.3" clock: dependency: transitive description: @@ -113,6 +153,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.18.0" + convert: + dependency: transitive + description: + name: convert + sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + url: "https://pub.dev" + source: hosted + version: "3.1.1" cross_file: dependency: transitive description: @@ -153,6 +201,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.7" + dart_style: + dependency: transitive + description: + name: dart_style + sha256: "99e066ce75c89d6b29903d788a7bb9369cf754f7b24bf70bf4b6d6d6b26853b9" + url: "https://pub.dev" + source: hosted + version: "2.3.6" fake_async: dependency: transitive description: @@ -232,14 +288,22 @@ packages: description: flutter source: sdk version: "0.0.0" + glob: + dependency: transitive + description: + name: glob + sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" + url: "https://pub.dev" + source: hosted + version: "2.1.2" go_router: dependency: transitive description: name: go_router - sha256: b465e99ce64ba75e61c8c0ce3d87b66d8ac07f0b35d0a7e0263fcfc10f99e836 + sha256: abec47eb8c8c36ebf41d0a4c64dbbe7f956e39a012b3aafc530e951bdc12fe3f url: "https://pub.dev" source: hosted - version: "13.2.5" + version: "14.1.4" google_fonts: dependency: "direct main" description: @@ -280,30 +344,38 @@ packages: url: "https://pub.dev" source: hosted version: "4.1.7" + json_annotation: + dependency: transitive + description: + name: json_annotation + sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" + url: "https://pub.dev" + source: hosted + version: "4.9.0" leak_tracker: dependency: transitive description: name: leak_tracker - sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" url: "https://pub.dev" source: hosted - version: "10.0.0" + version: "10.0.4" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.3" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.1" lints: dependency: transitive description: @@ -356,18 +428,32 @@ packages: dependency: transitive description: name: meta - sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 + sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.12.0" mix: + dependency: "direct overridden" + description: + path: "../../mix/packages/mix" + relative: true + source: path + version: "1.2.0" + mix_annotations: dependency: transitive description: - name: mix - sha256: "68d46b5829beabd8589eec2388765230b33a9d7b8fd508758eb23fb9e09a1ce7" + name: mix_annotations + sha256: f77b013274e5c61508a28b7142928ca5593d40693418163812d05f5ac8cd06a4 url: "https://pub.dev" source: hosted - version: "1.0.0-beta.13" + version: "0.2.0" + mix_generator: + dependency: "direct overridden" + description: + path: "../../mix/packages/mix_generator" + relative: true + source: path + version: "0.2.0" octo_image: dependency: transitive description: @@ -376,6 +462,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.0" + package_config: + dependency: transitive + description: + name: package_config + sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" + url: "https://pub.dev" + source: hosted + version: "2.1.0" path: dependency: transitive description: @@ -472,6 +566,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.8" + pub_semver: + dependency: transitive + description: + name: pub_semver + sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8 + url: "https://pub.dev" + source: hosted + version: "1.3.0" qr: dependency: transitive description: @@ -516,31 +626,39 @@ packages: dependency: transitive description: name: signals - sha256: "623a12333d53aeeaebeca83db2c7be04d09c46226d1bf9e3b5023fd1517399ed" + sha256: "94927d4069a158a6a20ad98990e6c67faeeed4ae6af681c1696fb98f3fbd5d2e" url: "https://pub.dev" source: hosted - version: "5.2.0" + version: "5.2.2" signals_core: dependency: transitive description: name: signals_core - sha256: e6d4940367e595c49fb93c1b918bfb03459d60ef7b7f9469befb5c236b6e20d0 + sha256: e5888685b9a3cff7c9814bd433195b1f76d0bfa3eae135e0a2f4ff5c48a56a1c url: "https://pub.dev" source: hosted - version: "5.1.0" + version: "5.2.2" signals_flutter: dependency: transitive description: name: signals_flutter - sha256: "74e78aa2da49984c32576817fc878f16feb6f1e57278898835659cc85a023f9f" + sha256: "1c202bc5136fbe1d8d71b66202e8f71bc10b957ca678c1f44d0d3af2aeb678cc" url: "https://pub.dev" source: hosted - version: "5.2.0" + version: "5.2.2" sky_engine: dependency: transitive description: flutter source: sdk version: "0.0.99" + source_gen: + dependency: transitive + description: + name: source_gen + sha256: "14658ba5f669685cd3d63701d01b31ea748310f7ab854e471962670abcf57832" + url: "https://pub.dev" + source: hosted + version: "1.5.0" source_span: dependency: transitive description: @@ -632,10 +750,10 @@ packages: dependency: transitive description: name: test_api - sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" + sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" url: "https://pub.dev" source: hosted - version: "0.6.1" + version: "0.7.0" type_plus: dependency: transitive description: @@ -752,10 +870,10 @@ packages: dependency: transitive description: name: vm_service - sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 + sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" url: "https://pub.dev" source: hosted - version: "13.0.0" + version: "14.2.1" watcher: dependency: transitive description: @@ -784,10 +902,10 @@ packages: dependency: transitive description: name: window_manager - sha256: b3c895bdf936c77b83c5254bec2e6b3f066710c1f89c38b20b8acc382b525494 + sha256: "8699323b30da4cdbe2aa2e7c9de567a6abd8a97d9a5c850a3c86dcd0b34bbfbf" url: "https://pub.dev" source: hosted - version: "0.3.8" + version: "0.3.9" xdg_directories: dependency: transitive description: diff --git a/example/pubspec_overrides.yaml b/example/pubspec_overrides.yaml new file mode 100644 index 0000000..e9e5b6a --- /dev/null +++ b/example/pubspec_overrides.yaml @@ -0,0 +1,5 @@ +dependency_overrides: + mix_generator: + path: ../../mix/packages/mix_generator + mix: + path: ../../mix/packages/mix \ No newline at end of file diff --git a/example/superdeck/generated/thumb_IrZnYqye.png b/example/superdeck/generated/thumb_IrZnYqye.png index 58d8378..0ae204a 100644 Binary files a/example/superdeck/generated/thumb_IrZnYqye.png and b/example/superdeck/generated/thumb_IrZnYqye.png differ diff --git a/example/superdeck/generated/thumb_SwkEymrr.png b/example/superdeck/generated/thumb_SwkEymrr.png index 501b3ef..abaada8 100644 Binary files a/example/superdeck/generated/thumb_SwkEymrr.png and b/example/superdeck/generated/thumb_SwkEymrr.png differ diff --git a/example/superdeck/generated/thumb_aShu2Vm6.png b/example/superdeck/generated/thumb_aShu2Vm6.png index 5051e7f..d9993ed 100644 Binary files a/example/superdeck/generated/thumb_aShu2Vm6.png and b/example/superdeck/generated/thumb_aShu2Vm6.png differ diff --git a/example/superdeck/generated/thumb_bt3HCjyv.png b/example/superdeck/generated/thumb_bt3HCjyv.png index 04da2a1..e0d3bce 100644 Binary files a/example/superdeck/generated/thumb_bt3HCjyv.png and b/example/superdeck/generated/thumb_bt3HCjyv.png differ diff --git a/example/superdeck/generated/thumb_dBrctVs2.png b/example/superdeck/generated/thumb_dBrctVs2.png index b4ee618..3e4bef6 100644 Binary files a/example/superdeck/generated/thumb_dBrctVs2.png and b/example/superdeck/generated/thumb_dBrctVs2.png differ diff --git a/example/superdeck/generated/thumb_zXfqPfVD.png b/example/superdeck/generated/thumb_zXfqPfVD.png index 6b42d5e..c32bee5 100644 Binary files a/example/superdeck/generated/thumb_zXfqPfVD.png and b/example/superdeck/generated/thumb_zXfqPfVD.png differ diff --git a/example/web/index.html b/example/web/index.html index 280c56e..4b6ba3f 100644 --- a/example/web/index.html +++ b/example/web/index.html @@ -1,19 +1,6 @@ - @@ -32,10 +19,7 @@ Presentation - + -
-
-
Loading Superdeck...
-
+
diff --git a/lib/builder/slide_parser.dart b/lib/builder/slide_parser.dart index e6d02c3..e4b18ad 100644 --- a/lib/builder/slide_parser.dart +++ b/lib/builder/slide_parser.dart @@ -1,4 +1,4 @@ -import '../helpers/config.dart'; +import '../helpers/config_model.dart'; import '../helpers/deep_merge.dart'; import '../helpers/utils.dart'; import '../models/slide_model.dart'; diff --git a/lib/builder/slides_loader.dart b/lib/builder/slides_loader.dart index 90dc100..00a2f31 100644 --- a/lib/builder/slides_loader.dart +++ b/lib/builder/slides_loader.dart @@ -56,7 +56,7 @@ class SlidesLoader { void listen( FutureOr Function() onChange, ) { - _listenerSub?.cancel(); + // _listenerSub?.cancel(); _listenerSub = _projectService.watcher.events.listen((_) => onChange()); } diff --git a/lib/components/atoms/cache_image_widget.dart b/lib/components/atoms/cache_image_widget.dart index 8e0c54b..4de8f1f 100644 --- a/lib/components/atoms/cache_image_widget.dart +++ b/lib/components/atoms/cache_image_widget.dart @@ -2,6 +2,7 @@ import 'dart:io'; import 'dart:math'; import 'package:cached_network_image/cached_network_image.dart'; +import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import 'package:signals/signals_flutter.dart'; @@ -21,7 +22,7 @@ class CacheImage extends StatelessWidget { required this.url, this.fit = BoxFit.cover, this.alignment = Alignment.center, - this.spec = const ImageSpec.empty(), + this.spec = const ImageSpec(), required this.size, super.key, }); diff --git a/lib/components/atoms/loading_indicator.dart b/lib/components/atoms/loading_indicator.dart new file mode 100644 index 0000000..fefaf77 --- /dev/null +++ b/lib/components/atoms/loading_indicator.dart @@ -0,0 +1,213 @@ +import 'package:flutter/material.dart'; + +class LoadingOverlay extends StatefulWidget { + final bool isLoading; + final Widget child; + + const LoadingOverlay({ + super.key, + required this.isLoading, + required this.child, + }); + + @override + _LoadingOverlayState createState() => _LoadingOverlayState(); +} + +class _LoadingOverlayState extends State + with SingleTickerProviderStateMixin { + late AnimationController _animationController; + late Animation _opacityAnimation; + + @override + void initState() { + super.initState(); + _animationController = AnimationController( + vsync: this, + duration: const Duration(milliseconds: 500), + ); + _opacityAnimation = + Tween(begin: 1.0, end: 0.0).animate(_animationController); + } + + @override + void didUpdateWidget(LoadingOverlay oldWidget) { + super.didUpdateWidget(oldWidget); + if (!widget.isLoading && oldWidget.isLoading) { + _animationController.forward().then((_) { + setState(() {}); + }); + } else if (widget.isLoading && !oldWidget.isLoading) { + _animationController.reverse().then((_) { + setState(() {}); + }); + } + } + + @override + void dispose() { + _animationController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Stack( + children: [ + widget.child, + if (widget.isLoading || _animationController.isAnimating) + FadeTransition( + opacity: _opacityAnimation, + child: Container( + color: Colors.black87, + child: const Center( + child: IsometricLoading(), + ), + ), + ), + ], + ); + } +} + +class IsometricLoading extends StatefulWidget { + const IsometricLoading({super.key, this.color = Colors.white}); + + final Color color; + @override + _IsometricLoadingState createState() => _IsometricLoadingState(); +} + +class _IsometricLoadingState extends State + with SingleTickerProviderStateMixin { + late AnimationController _animationController; + late Animation _animation; + late final List _colors = [ + widget.color, + widget.color.withOpacity(0.7), + widget.color.withOpacity(0.4), + widget.color.withOpacity(0.2), + ]; + + @override + void initState() { + super.initState(); + _animationController = AnimationController( + vsync: this, + duration: const Duration(milliseconds: 500), + )..repeat(reverse: true); + _animation = Tween(begin: 0, end: 1).animate( + CurvedAnimation( + parent: _animationController, + curve: Curves.easeInOut, + ), + ); + } + + @override + void dispose() { + _animationController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return AnimatedBuilder( + animation: _animation, + builder: (context, child) { + return Transform.scale( + scale: 0.2, + child: CustomPaint( + painter: IsometricLoadingPainter( + colors: List.generate(4, (index) { + final startColorIndex = + ((_animation.value * _colors.length).floor() + index) % + _colors.length; + final endColorIndex = (startColorIndex == _colors.length - 1) + ? 0 + : startColorIndex + 1; + final startColor = _colors[startColorIndex]; + final endColor = _colors[endColorIndex]; + final colorProgress = (_animation.value * _colors.length) % 1.0; + return Color.lerp(startColor, endColor, colorProgress)!; + }), + )), + ); + }, + ); + } +} + +class IsometricLoadingPainter extends CustomPainter { + final List colors; + + IsometricLoadingPainter({required this.colors}); + + @override + void paint(Canvas canvas, Size size) { + final path1 = Path() + ..moveTo(92.2116, 119.9706) + ..lineTo(0, 66.7358) + ..lineTo(0, 132.1824) + ..lineTo(71.075, 173.2154) + ..lineTo(71.075, 189.8452) + ..lineTo(0, 148.812) + ..lineTo(0, 173.2154) + ..lineTo(92.2116, 226.45) + ..lineTo(92.2116, 161.0138) + ..lineTo(21.1366, 119.9706) + ..lineTo(21.1366, 103.341) + ..lineTo(92.2116, 144.384) + ..close(); + + final path2 = Path() + ..moveTo(28.9178, 41.045) + ..lineTo(7.78124, 53.2566) + ..lineTo(107.7764, 110.9884) + ..lineTo(107.7764, 202.038) + ..lineTo(128.9128, 214.25) + ..lineTo(128.9128, 98.7868) + ..close(); + + final path3 = Path() + ..moveTo(64.4646, 20.5274) + ..lineTo(43.3282, 32.7388) + ..lineTo(143.3232, 90.4706) + ..lineTo(143.3232, 181.521) + ..lineTo(164.4598, 193.7328) + ..lineTo(164.4598, 78.269) + ..close(); + + final path4 = Path() + ..moveTo(78.875, 12.21148) + ..lineTo(178.87, 69.9434) + ..lineTo(178.87, 160.994) + ..lineTo(200.006, 173.2054) + ..lineTo(200.006, 57.7318) + ..lineTo(169.2662, 39.99) + ..lineTo(100.0116, 0) + ..close(); + + final paint1 = Paint() + ..color = colors[0] + ..style = PaintingStyle.fill; + final paint2 = Paint() + ..color = colors[1] + ..style = PaintingStyle.fill; + final paint3 = Paint() + ..color = colors[2] + ..style = PaintingStyle.fill; + final paint4 = Paint() + ..color = colors[3] + ..style = PaintingStyle.fill; + + canvas.drawPath(path1, paint1); + canvas.drawPath(path2, paint2); + canvas.drawPath(path3, paint3); + canvas.drawPath(path4, paint4); + } + + @override + bool shouldRepaint(IsometricLoadingPainter oldDelegate) => + oldDelegate.colors != colors; +} diff --git a/lib/components/atoms/markdown_viewer.dart b/lib/components/atoms/markdown_viewer.dart index 5bb316b..12f375c 100644 --- a/lib/components/atoms/markdown_viewer.dart +++ b/lib/components/atoms/markdown_viewer.dart @@ -87,7 +87,7 @@ class SlideSpecTween extends Tween { SlideSpecTween({super.begin, super.end}); @override SlideSpec lerp(double t) { - return begin?.lerp(end!, t) ?? end ?? const SlideSpec.empty(); + return begin?.lerp(end!, t) ?? end ?? SlideSpec(); } } diff --git a/lib/components/atoms/slide_thumbnail.dart b/lib/components/atoms/slide_thumbnail.dart index 693abc1..5d0a2fa 100644 --- a/lib/components/atoms/slide_thumbnail.dart +++ b/lib/components/atoms/slide_thumbnail.dart @@ -9,14 +9,15 @@ import '../../services/snapshot_service.dart'; import '../../superdeck.dart'; import '../molecules/scaled_app.dart'; import 'cache_image_widget.dart'; +import 'loading_indicator.dart'; import 'slide_view.dart'; final _previewStyle = AnimatedStyle( Style( - box.color.grey.shade900(), - box.margin.all(8), - box.border.all.width(2), - box.shadow( + $box.color.grey.shade900(), + $box.margin.all(8), + $box.border.all.width(2), + $box.shadow( color: Colors.black.withOpacity(0.5), blurRadius: 4, spreadRadius: 1, @@ -100,33 +101,36 @@ class _SlideThumbnailState extends State { final result = _thumbnailLoader.watch(context); - final child = result.map( - data: (path) { - return Image( - image: getImageProvider( - context: context, - url: path, - targetSize: constraints.biggest, - ), - ); - }, - loading: () { - return const Center( - child: CircularProgressIndicator(), - ); - }, - error: (error, _) { - return const Center( - child: Text('Error loading image'), - ); - }, + final child = LoadingOverlay( + isLoading: result.isLoading, + child: result.map( + data: (path) { + return Image( + image: getImageProvider( + context: context, + url: path, + targetSize: constraints.biggest, + ), + ); + }, + loading: () { + return const Center( + child: CircularProgressIndicator(), + ); + }, + error: (error, _) { + return const Center( + child: Text('Error loading image'), + ); + }, + ), ); return GestureDetector( onTap: widget.onTap, child: PreviewBox( style: Style( - box.border.all.color(selectedColor), + $box.border.all.color(selectedColor), ), child: AbsorbPointer( child: AspectRatio( @@ -195,7 +199,7 @@ class SlideThumbnailDynamic extends StatelessWidget { onTap: onTap, child: PreviewBox( style: Style( - box.border.all.color(selectedColor), + $box.border.all.color(selectedColor), ), child: AbsorbPointer( child: AspectRatio( diff --git a/lib/components/atoms/slide_view.dart b/lib/components/atoms/slide_view.dart index 7422a14..60a60b4 100644 --- a/lib/components/atoms/slide_view.dart +++ b/lib/components/atoms/slide_view.dart @@ -48,6 +48,7 @@ class SlideView extends StatelessWidget { transition: slide.transition, child: Pressable( onPress: () {}, + autofocus: true, child: SpecBuilder( style: variantStyle, builder: (context) { diff --git a/lib/components/molecules/slide_preview.dart b/lib/components/molecules/slide_preview.dart index af4eef7..9effa3e 100644 --- a/lib/components/molecules/slide_preview.dart +++ b/lib/components/molecules/slide_preview.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import '../../helpers/measure_size.dart'; import '../../helpers/utils.dart'; +import '../../styles/style_util.dart'; import '../../superdeck.dart'; import '../atoms/markdown_viewer.dart'; import '../atoms/slide_view.dart'; @@ -55,10 +56,11 @@ class SlideMarkdownPreview extends StatelessWidget { final rawYaml = slide.raw; final options = '#### Options\n```yaml\n${rawYaml.trim()}\n```\n'; final data = '#### Content\n```markdown\n${slide.data}\n```\n'; + final s = SlideSpecUtility.self; return SpecBuilder( style: defaultStyle.merge( Style( - $deck.code.span.fontSize(14), + s.code.span.fontSize(14), ), ), builder: (mix) { diff --git a/lib/components/molecules/split_view.dart b/lib/components/molecules/split_view.dart index 2bb4c46..c2eeed9 100644 --- a/lib/components/molecules/split_view.dart +++ b/lib/components/molecules/split_view.dart @@ -7,10 +7,10 @@ import 'slide_thumbnail_list.dart'; // ignore: non_constant_identifier_names final SlidePreviewBox = Style( - box.color.grey.shade900(), - box.margin.all(8), - box.maxHeight(140), - box.shadow( + $box.color.grey.shade900(), + $box.margin.all(8), + $box.maxHeight(140), + $box.shadow( color: Colors.black.withOpacity(0.5), blurRadius: 4, spreadRadius: 1, diff --git a/lib/components/superdeck_app.dart b/lib/components/superdeck_app.dart index 53afe63..e153cda 100644 --- a/lib/components/superdeck_app.dart +++ b/lib/components/superdeck_app.dart @@ -13,9 +13,11 @@ import '../helpers/constants.dart'; import '../helpers/theme.dart'; import '../screens/export_screen.dart'; import '../screens/home_screen.dart'; +import 'atoms/loading_indicator.dart'; import 'molecules/exception_widget.dart'; final kAppKey = GlobalKey(); +final _uniqueKey = UniqueKey(); class SuperDeckApp extends StatefulWidget { const SuperDeckApp({ @@ -78,14 +80,6 @@ class _SuperDeckAppState extends State { @override Widget build(BuildContext context) { - Widget renderLoading() { - return const Scaffold( - body: Center( - child: CircularProgressIndicator(), - ), - ); - } - return Theme( data: theme, child: Builder(builder: (context) { @@ -100,15 +94,19 @@ class _SuperDeckAppState extends State { builder: (context, child) { final result = _initialize.watch(context); - return result.map( - data: (_) => child!, - loading: () => renderLoading(), - error: (error, _) { - return ExceptionWidget( - error, - onRetry: _initialize.reload, - ); - }, + return LoadingOverlay( + isLoading: result.isLoading, + key: _uniqueKey, + child: result.map( + data: (_) => child!, + loading: () => const SizedBox(), + error: (error, _) { + return ExceptionWidget( + error, + onRetry: _initialize.reload, + ); + }, + ), ); }, ), diff --git a/lib/helpers/config.dart b/lib/helpers/config_model.dart similarity index 96% rename from lib/helpers/config.dart rename to lib/helpers/config_model.dart index 18c7289..39d42e1 100644 --- a/lib/helpers/config.dart +++ b/lib/helpers/config_model.dart @@ -3,11 +3,11 @@ import 'dart:io'; import 'package:dart_mappable/dart_mappable.dart'; import '../models/options_model.dart'; -import '../schema/schema.dart'; +import '../schema/schema_model.dart'; import '../schema/schema_values.dart'; import 'utils.dart'; -part 'config.mapper.dart'; +part 'config_model.mapper.dart'; @MappableClass() abstract class Config with ConfigMappable { diff --git a/lib/helpers/config.mapper.dart b/lib/helpers/config_model.mapper.dart similarity index 99% rename from lib/helpers/config.mapper.dart rename to lib/helpers/config_model.mapper.dart index 6a51474..69731fa 100644 --- a/lib/helpers/config.mapper.dart +++ b/lib/helpers/config_model.mapper.dart @@ -4,7 +4,7 @@ // ignore_for_file: unused_element, unnecessary_cast, override_on_non_overriding_member // ignore_for_file: strict_raw_type, inference_failure_on_untyped_parameter -part of 'config.dart'; +part of 'config_model.dart'; class ConfigMapper extends ClassMapperBase { ConfigMapper._(); diff --git a/lib/helpers/layout_builder.dart b/lib/helpers/layout_builder.dart index 80a7c6c..1701948 100644 --- a/lib/helpers/layout_builder.dart +++ b/lib/helpers/layout_builder.dart @@ -47,16 +47,18 @@ class InvalidSlideBuilder extends SlideBuilder { Widget build(BuildContext context) { const red = Color.fromARGB(255, 166, 6, 6); + final s = SlideSpecUtility.self; + final style = Style( - $deck.textStyle.color(Colors.white), - $deck.h1.textStyle.color(const Color.fromARGB(255, 71, 1, 1)), - $deck.h1.textStyle.fontSize(36.0), - $deck.h1.textStyle.bold(), - $deck.h2.padding.top(0), - $deck.h2.textStyle.bold(), - $deck.h2.textStyle.color.yellow(), - $deck.code.span.color.yellow(), - $deck.code.span.backgroundColor(const Color.fromARGB(255, 84, 6, 6)), + s.textStyle.color(Colors.white), + s.h1.textStyle.color(const Color.fromARGB(255, 71, 1, 1)), + s.h1.textStyle.fontSize(36.0), + s.h1.textStyle.bold(), + s.h2.padding.top(0), + s.h2.textStyle.bold(), + s.h2.textStyle.color.yellow(), + s.code.span.color.yellow(), + s.code.span.backgroundColor(const Color.fromARGB(255, 84, 6, 6)), ); return SpecBuilder( diff --git a/lib/models/options_model.dart b/lib/models/options_model.dart index d277eaa..bf5a0fb 100644 --- a/lib/models/options_model.dart +++ b/lib/models/options_model.dart @@ -4,7 +4,7 @@ import 'package:recase/recase.dart'; import '../helpers/layout_builder.dart'; import '../helpers/mappers.dart'; -import '../schema/schema.dart'; +import '../schema/schema_model.dart'; import '../schema/schema_values.dart'; import 'slide_model.dart'; diff --git a/lib/models/slide_model.dart b/lib/models/slide_model.dart index 263e18c..d6c9154 100644 --- a/lib/models/slide_model.dart +++ b/lib/models/slide_model.dart @@ -1,9 +1,10 @@ import 'package:dart_mappable/dart_mappable.dart'; -import '../helpers/config.dart'; +import '../helpers/config_model.dart'; import '../helpers/section_tag.dart'; import '../helpers/utils.dart'; -import '../schema/schema.dart'; +import '../schema/schema_model.dart'; +import '../styles/style_util.dart'; import '../superdeck.dart'; part 'slide_model.mapper.dart'; diff --git a/lib/providers/controller.dart b/lib/providers/controller.dart index 154d740..25a4598 100644 --- a/lib/providers/controller.dart +++ b/lib/providers/controller.dart @@ -8,6 +8,7 @@ import 'package:signals/signals_flutter.dart'; import '../builder/slides_loader.dart'; import '../helpers/constants.dart'; import '../services/project_service.dart'; +import '../styles/style_util.dart'; import '../superdeck.dart'; final sdController = SDController.instance; diff --git a/lib/schema/schema.dart b/lib/schema/schema_model.dart similarity index 99% rename from lib/schema/schema.dart rename to lib/schema/schema_model.dart index d9dcc17..282711b 100644 --- a/lib/schema/schema.dart +++ b/lib/schema/schema_model.dart @@ -3,7 +3,7 @@ import 'package:dart_mappable/dart_mappable.dart'; import 'schema_values.dart'; import 'validators.dart'; -part 'schema.mapper.dart'; +part 'schema_model.mapper.dart'; typedef JSON = Map; diff --git a/lib/schema/schema.mapper.dart b/lib/schema/schema_model.mapper.dart similarity index 99% rename from lib/schema/schema.mapper.dart rename to lib/schema/schema_model.mapper.dart index 1298e20..545c22c 100644 --- a/lib/schema/schema.mapper.dart +++ b/lib/schema/schema_model.mapper.dart @@ -4,7 +4,7 @@ // ignore_for_file: unused_element, unnecessary_cast, override_on_non_overriding_member // ignore_for_file: strict_raw_type, inference_failure_on_untyped_parameter -part of 'schema.dart'; +part of 'schema_model.dart'; class SchemaValidationErrorMapper extends ClassMapperBase { diff --git a/lib/schema/schema_values.dart b/lib/schema/schema_values.dart index 9a82cf0..5a1844f 100644 --- a/lib/schema/schema_values.dart +++ b/lib/schema/schema_values.dart @@ -1,4 +1,4 @@ -import 'schema.dart'; +import 'schema_model.dart'; import 'validators.dart'; abstract class SchemaValue { diff --git a/lib/schema/validators.dart b/lib/schema/validators.dart index f21b57e..f63c48f 100644 --- a/lib/schema/validators.dart +++ b/lib/schema/validators.dart @@ -1,4 +1,4 @@ -import 'schema.dart'; +import 'schema_model.dart'; abstract class Validator { const Validator(); diff --git a/lib/screens/export_screen.dart b/lib/screens/export_screen.dart index 9565696..20f2aed 100644 --- a/lib/screens/export_screen.dart +++ b/lib/screens/export_screen.dart @@ -340,7 +340,7 @@ class _ExportingProcessScreenState extends State { return Stack( children: [ Container( - color: Theme.of(context).colorScheme.background, + color: Theme.of(context).colorScheme.surface, ), Container( color: Colors.black.withOpacity(0.8), diff --git a/lib/services/project_service.dart b/lib/services/project_service.dart index 1bfffd7..dc2e5ab 100644 --- a/lib/services/project_service.dart +++ b/lib/services/project_service.dart @@ -8,7 +8,7 @@ import 'package:flutter/services.dart'; import 'package:path/path.dart' as p; import 'package:watcher/watcher.dart'; -import '../helpers/config.dart'; +import '../helpers/config_model.dart'; import '../helpers/constants.dart'; import '../helpers/extensions.dart'; import '../superdeck.dart'; @@ -36,6 +36,8 @@ class ProjectService { File get configRef => File(p.join(assetsDir.path, 'config.json')); File get assetsRef => File(p.join(assetsDir.path, 'assets.json')); + late final watcher = FileWatcher(markdownFile.path); + Future ensureExists() async { await assetsDir.ensureExists(); await generatedAssetsDir.ensureExists(); @@ -187,8 +189,6 @@ class ProjectService { return assets; } - - late final watcher = FileWatcher(markdownFile.path); } List _parseList( diff --git a/lib/services/snapshot_service.dart b/lib/services/snapshot_service.dart index bd138e4..ea0bd50 100644 --- a/lib/services/snapshot_service.dart +++ b/lib/services/snapshot_service.dart @@ -115,7 +115,10 @@ class SnapshotService { child: repaintBoundary, ), configuration: ViewConfiguration( - size: logicalSize, + logicalConstraints: BoxConstraints( + maxWidth: logicalSize.width, + maxHeight: logicalSize.height, + ), devicePixelRatio: pixelRatio, ), ); diff --git a/lib/styles/style_attribute.dart b/lib/styles/style_attribute.dart deleted file mode 100644 index 1239750..0000000 --- a/lib/styles/style_attribute.dart +++ /dev/null @@ -1,119 +0,0 @@ -import 'package:mix/mix.dart'; - -import 'style_dto.dart'; -import 'style_spec.dart'; - -class SlideSpecAttribute extends SpecAttribute { - final MdTextStyleDto? headline1; - final MdTextStyleDto? headline2; - final MdTextStyleDto? headline3; - final MdTextStyleDto? headline4; - final MdTextStyleDto? headline5; - final MdTextStyleDto? headline6; - final MdTextStyleDto? paragraph; - final TextStyleDto? link; - final double? blockSpacing; - final MdDividerDto? divider; - final MdListDto? list; - final MdTableDto? table; - final MdCodeDto? code; - final MdBlockQuoteDto? blockquote; - final BoxSpecAttribute? innerContainer; - final BoxSpecAttribute? outerContainer; - final BoxSpecAttribute? contentContainer; - final ImageSpecAttribute? image; - - const SlideSpecAttribute({ - this.headline1, - this.headline2, - this.headline3, - this.headline4, - this.headline5, - this.headline6, - this.paragraph, - this.link, - this.blockSpacing, - this.divider, - this.list, - this.table, - this.code, - this.blockquote, - this.innerContainer, - this.outerContainer, - this.contentContainer, - this.image, - }); - - @override - SlideSpecAttribute merge(SlideSpecAttribute? other) { - return SlideSpecAttribute( - headline1: headline1?.merge(other?.headline1) ?? other?.headline1, - headline2: headline2?.merge(other?.headline2) ?? other?.headline2, - headline3: headline3?.merge(other?.headline3) ?? other?.headline3, - headline4: headline4?.merge(other?.headline4) ?? other?.headline4, - headline5: headline5?.merge(other?.headline5) ?? other?.headline5, - headline6: headline6?.merge(other?.headline6) ?? other?.headline6, - paragraph: paragraph?.merge(other?.paragraph) ?? other?.paragraph, - link: link?.merge(other?.link) ?? other?.link, - blockSpacing: blockSpacing ?? other?.blockSpacing, - divider: divider?.merge(other?.divider) ?? other?.divider, - list: list?.merge(other?.list) ?? other?.list, - table: table?.merge(other?.table) ?? other?.table, - code: code?.merge(other?.code) ?? other?.code, - blockquote: blockquote?.merge(other?.blockquote) ?? other?.blockquote, - innerContainer: - innerContainer?.merge(other?.innerContainer) ?? other?.innerContainer, - outerContainer: - outerContainer?.merge(other?.outerContainer) ?? other?.outerContainer, - contentContainer: contentContainer?.merge(other?.contentContainer) ?? - other?.contentContainer, - image: image?.merge(other?.image) ?? other?.image, - ); - } - - @override - SlideSpec resolve(MixData mix) { - return SlideSpec( - headline1: headline1?.resolve(mix), - headline2: headline2?.resolve(mix), - headline3: headline3?.resolve(mix), - headline4: headline4?.resolve(mix), - headline5: headline5?.resolve(mix), - headline6: headline6?.resolve(mix), - paragraph: paragraph?.resolve(mix), - link: link?.resolve(mix), - blockSpacing: blockSpacing, - divider: divider?.resolve(mix), - list: list?.resolve(mix), - table: table?.resolve(mix), - code: code?.resolve(mix), - blockquote: blockquote?.resolve(mix), - innerContainer: innerContainer?.resolve(mix), - outerContainer: outerContainer?.resolve(mix), - contentContainer: contentContainer?.resolve(mix), - image: image?.resolve(mix), - ); - } - - @override - get props => [ - headline1, - headline2, - headline3, - headline4, - headline5, - headline6, - paragraph, - link, - blockSpacing, - divider, - list, - table, - code, - blockquote, - innerContainer, - outerContainer, - contentContainer, - image, - ]; -} diff --git a/lib/styles/style_dto.dart b/lib/styles/style_dto.dart deleted file mode 100644 index 8af5589..0000000 --- a/lib/styles/style_dto.dart +++ /dev/null @@ -1,439 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:markdown_viewer/markdown_viewer.dart'; -import 'package:mix/mix.dart'; - -import 'style_spec.dart'; - -class MdTextStyleDto extends Dto { - final TextStyleDto? textStyle; - final SpacingDto? padding; - - const MdTextStyleDto({ - this.textStyle, - this.padding, - }); - - static MdTextStyleDto from(MdTextStyle style) { - return MdTextStyleDto( - textStyle: TextStyleDto.maybeAs(style.textStyle), - padding: SpacingDto.maybeFrom(style.padding), - ); - } - - static MdTextStyleDto? maybeFrom(MdTextStyle? style) { - return style != null ? from(style) : null; - } - - @override - MdTextStyleDto merge(MdTextStyleDto? other) { - return MdTextStyleDto( - textStyle: textStyle?.merge(other?.textStyle) ?? other?.textStyle, - padding: padding?.merge(other?.padding) ?? other?.padding, - ); - } - - @override - MdTextStyle resolve(MixData mix) { - return MdTextStyle( - textStyle: textStyle?.resolve(mix), - padding: padding?.resolve(mix) as EdgeInsets?, - ); - } - - @override - get props => [textStyle, padding]; -} - -class MdListDto extends Dto { - final TextStyleDto? textStyle; - final TextStyleDto? item; - final TextStyleDto? itemMarker; - final double? itemMarkerTrailingSpace; - final double? itemMinIndent; - - const MdListDto({ - this.textStyle, - this.item, - this.itemMarker, - this.itemMinIndent, - this.itemMarkerTrailingSpace, - }); - - static MdListDto from(MdList style) { - return MdListDto( - textStyle: TextStyleDto.maybeAs(style.list), - item: TextStyleDto.maybeAs(style.listItem), - itemMinIndent: style.listItemMinIndent, - itemMarker: TextStyleDto.maybeAs(style.listItemMarker), - itemMarkerTrailingSpace: style.listItemMarkerTrailingSpace, - ); - } - - static MdListDto? maybeFrom(MdList? style) { - return style != null ? from(style) : null; - } - - @override - MdListDto merge(MdListDto? other) { - return MdListDto( - textStyle: textStyle?.merge(other?.textStyle) ?? other?.textStyle, - item: item?.merge(other?.item) ?? other?.item, - itemMinIndent: other?.itemMinIndent ?? itemMinIndent, - itemMarker: itemMarker?.merge(other?.itemMarker) ?? other?.itemMarker, - itemMarkerTrailingSpace: - other?.itemMarkerTrailingSpace ?? itemMarkerTrailingSpace, - ); - } - - @override - MdList resolve(MixData mix) { - return MdList( - list: textStyle?.resolve(mix), - listItem: item?.resolve(mix), - listItemMinIndent: itemMinIndent, - listItemMarker: itemMarker?.resolve(mix), - listItemMarkerTrailingSpace: itemMarkerTrailingSpace, - ); - } - - @override - get props => - [textStyle, item, itemMarker, itemMarkerTrailingSpace, itemMinIndent]; -} - -class MdDividerDto extends Dto { - final double? height; - final ColorDto? color; - final double? thickness; - - const MdDividerDto({ - this.height, - this.color, - this.thickness, - }); - - static MdDividerDto from(MdDivider style) { - return MdDividerDto( - height: style.dividerHeight, - color: ColorDto.maybeFrom(style.dividerColor), - thickness: style.dividerThickness, - ); - } - - static MdDividerDto? maybeFrom(MdDivider? style) { - return style != null ? from(style) : null; - } - - @override - MdDividerDto merge(MdDividerDto? other) { - return MdDividerDto( - height: other?.height ?? height, - color: color?.merge(other?.color) ?? other?.color, - thickness: other?.thickness ?? thickness, - ); - } - - @override - MdDivider resolve(MixData mix) { - return MdDivider( - dividerHeight: height, - dividerColor: color?.resolve(mix), - dividerThickness: thickness, - ); - } - - @override - get props => [height, color, thickness]; -} - -class MdBlockQuoteDto extends Dto { - final TextStyleDto? textStyle; - final BoxDecorationDto? decoration; - final SpacingDto? padding; - final SpacingDto? contentPadding; - - const MdBlockQuoteDto({ - this.textStyle, - this.decoration, - this.padding, - this.contentPadding, - }); - - static MdBlockQuoteDto from(MdBlockQuote style) { - return MdBlockQuoteDto( - textStyle: TextStyleDto.maybeAs(style.blockquote), - decoration: BoxDecorationDto.maybeFrom(style.blockquoteDecoration), - padding: SpacingDto.maybeFrom(style.blockquotePadding), - contentPadding: SpacingDto.maybeFrom(style.blockquoteContentPadding), - ); - } - - static MdBlockQuoteDto? maybeFrom(MdBlockQuote? style) { - return style != null ? from(style) : null; - } - - @override - MdBlockQuoteDto merge(MdBlockQuoteDto? other) { - return MdBlockQuoteDto( - textStyle: textStyle?.merge(other?.textStyle) ?? other?.textStyle, - decoration: (decoration?.merge(other?.decoration) ?? other?.decoration) - as BoxDecorationDto?, - padding: padding?.merge(other?.padding) ?? other?.padding, - contentPadding: - contentPadding?.merge(other?.contentPadding) ?? other?.contentPadding, - ); - } - - @override - MdBlockQuote resolve(MixData mix) { - return MdBlockQuote( - blockquote: textStyle?.resolve(mix), - blockquoteDecoration: decoration?.resolve(mix), - blockquotePadding: padding?.resolve(mix) as EdgeInsets?, - blockquoteContentPadding: contentPadding?.resolve(mix) as EdgeInsets?, - ); - } - - @override - get props => [textStyle, decoration, padding, contentPadding]; -} - -@immutable -class MdTableDto extends Dto { - final TextStyleDto? textStyle; - final TextStyleDto? head; - final TextStyleDto? body; - final TableBorderDto? border; - final BoxDecorationDto? rowDecoration; - final MarkdownAlternating? rowDecorationAlternating; - final SpacingDto? cellPadding; - final TableColumnWidth? columnWidth; - - const MdTableDto({ - this.textStyle, - this.head, - this.body, - this.border, - this.rowDecoration, - this.rowDecorationAlternating, - this.cellPadding, - this.columnWidth, - }); - - static MdTableDto from(MdTable style) { - return MdTableDto( - textStyle: TextStyleDto.maybeAs(style.table), - head: TextStyleDto.maybeAs(style.tableHead), - body: TextStyleDto.maybeAs(style.tableBody), - border: TableBorderDto.maybeFrom(style.tableBorder), - rowDecoration: BoxDecorationDto.maybeFrom(style.tableRowDecoration), - rowDecorationAlternating: style.tableRowDecorationAlternating, - cellPadding: SpacingDto.maybeFrom(style.tableCellPadding), - columnWidth: style.tableColumnWidth, - ); - } - - static MdTableDto? maybeFrom(MdTable? style) { - return style != null ? from(style) : null; - } - - @override - MdTableDto merge(MdTableDto? other) { - return MdTableDto( - textStyle: textStyle?.merge(other?.textStyle) ?? other?.textStyle, - head: head?.merge(other?.head) ?? other?.head, - body: body?.merge(other?.body) ?? other?.body, - border: other?.border ?? border, - rowDecoration: (rowDecoration?.merge(other?.rowDecoration) ?? - other?.rowDecoration) as BoxDecorationDto?, - rowDecorationAlternating: - other?.rowDecorationAlternating ?? rowDecorationAlternating, - cellPadding: cellPadding?.merge(other?.cellPadding) ?? other?.cellPadding, - columnWidth: other?.columnWidth ?? columnWidth, - ); - } - - @override - MdTable resolve(MixData mix) { - return MdTable( - table: textStyle?.resolve(mix), - tableHead: head?.resolve(mix), - tableBody: body?.resolve(mix), - tableBorder: border?.resolve(mix), - tableRowDecoration: rowDecoration?.resolve(mix), - tableRowDecorationAlternating: rowDecorationAlternating, - tableCellPadding: cellPadding?.resolve(mix) as EdgeInsets?, - tableColumnWidth: columnWidth, - ); - } - - @override - get props => [ - textStyle, - head, - body, - border, - rowDecoration, - rowDecorationAlternating, - cellPadding, - columnWidth, - ]; -} - -@immutable -class MdCodeDto extends Dto { - final TextStyleDto? span; - final TextStyleDto? textStyle; - final SpacingDto? padding; - final BoxDecorationDto? decoration; - - final ColorDto? copyIconColor; - - const MdCodeDto({ - this.textStyle, - this.span, - this.padding, - this.decoration, - this.copyIconColor, - }); - - static MdCodeDto from(MdCode style) { - return MdCodeDto( - span: TextStyleDto.maybeAs(style.codeSpan), - padding: SpacingDto.maybeFrom(style.codeblockPadding), - decoration: BoxDecorationDto.maybeFrom(style.codeblockDecoration), - copyIconColor: ColorDto.maybeFrom(style.copyIconColor), - textStyle: TextStyleDto.maybeAs(style.codeBlock), - ); - } - - static MdCodeDto? maybeFrom(MdCode? style) { - return style != null ? from(style) : null; - } - - @override - MdCodeDto merge(MdCodeDto? other) { - return MdCodeDto( - span: span?.merge(other?.span) ?? other?.span, - padding: padding?.merge(other?.padding) ?? other?.padding, - decoration: (decoration?.merge(other?.decoration) ?? other?.decoration) - as BoxDecorationDto?, - copyIconColor: - copyIconColor?.merge(other?.copyIconColor) ?? other?.copyIconColor, - textStyle: textStyle?.merge(other?.textStyle) ?? other?.textStyle, - ); - } - - @override - MdCode resolve(MixData mix) { - return MdCode( - codeSpan: span?.resolve(mix), - codeblockPadding: padding?.resolve(mix) as EdgeInsets?, - codeblockDecoration: decoration?.resolve(mix), - copyIconColor: copyIconColor?.resolve(mix), - codeBlock: textStyle?.resolve(mix), - ); - } - - @override - get props => [span, padding, decoration, copyIconColor, textStyle]; -} - -class TableBorderDto extends Dto { - final BorderSideDto? top; - final BorderSideDto? right; - final BorderSideDto? bottom; - final BorderSideDto? left; - final BorderSideDto? horizontalInside; - final BorderSideDto? verticalInside; - final BorderRadiusGeometryDto? borderRadius; - - static TableBorderDto from(TableBorder border) { - return TableBorderDto( - top: BorderSideDto.from(border.top), - right: BorderSideDto.from(border.right), - bottom: BorderSideDto.from(border.bottom), - left: BorderSideDto.from(border.left), - horizontalInside: BorderSideDto.from(border.horizontalInside), - verticalInside: BorderSideDto.from(border.verticalInside), - borderRadius: BorderRadiusGeometryDto.from(border.borderRadius), - ); - } - - factory TableBorderDto.all({ - Color color = const Color(0xFF000000), - double width = 1.0, - BorderStyle style = BorderStyle.solid, - BorderRadius borderRadius = BorderRadius.zero, - }) { - final side = BorderSideDto( - color: ColorDto(color), - width: width, - style: style, - ); - return TableBorderDto( - top: side, - right: side, - bottom: side, - left: side, - horizontalInside: side, - verticalInside: side, - borderRadius: BorderRadiusGeometryDto.from(borderRadius), - ); - } - - static TableBorderDto? maybeFrom(TableBorder? border) { - return border != null ? from(border) : null; - } - - const TableBorderDto({ - this.top, - this.right, - this.bottom, - this.left, - this.horizontalInside, - this.verticalInside, - this.borderRadius, - }); - - @override - TableBorderDto merge(TableBorderDto? other) { - return TableBorderDto( - top: top?.merge(other?.top) ?? other?.top, - right: right?.merge(other?.right) ?? other?.right, - bottom: bottom?.merge(other?.bottom) ?? other?.bottom, - left: left?.merge(other?.left) ?? other?.left, - horizontalInside: horizontalInside?.merge(other?.horizontalInside) ?? - other?.horizontalInside, - verticalInside: - verticalInside?.merge(other?.verticalInside) ?? other?.verticalInside, - borderRadius: - borderRadius?.merge(other?.borderRadius) ?? other?.borderRadius, - ); - } - - @override - TableBorder resolve(MixData mix) { - return TableBorder( - top: top?.resolve(mix) ?? BorderSide.none, - right: right?.resolve(mix) ?? BorderSide.none, - bottom: bottom?.resolve(mix) ?? BorderSide.none, - left: left?.resolve(mix) ?? BorderSide.none, - horizontalInside: horizontalInside?.resolve(mix) ?? BorderSide.none, - verticalInside: verticalInside?.resolve(mix) ?? BorderSide.none, - borderRadius: - borderRadius?.resolve(mix) as BorderRadius? ?? BorderRadius.zero, - ); - } - - @override - get props => [ - top, - right, - bottom, - left, - horizontalInside, - verticalInside, - borderRadius - ]; -} diff --git a/lib/styles/style_spec.dart b/lib/styles/style_spec.dart index 2b72258..8c19a0e 100644 --- a/lib/styles/style_spec.dart +++ b/lib/styles/style_spec.dart @@ -1,446 +1,211 @@ -import 'dart:ui'; - import 'package:flutter/material.dart'; import 'package:markdown_viewer/markdown_viewer.dart'; import 'package:mix/mix.dart'; +import 'package:mix_annotations/mix_annotations.dart'; + +part 'style_spec.g.dart'; -import 'style_attribute.dart'; +const _mdTextStyle = MixableFieldDto(type: 'MdTextStyleAttribute'); +const _mdCode = MixableFieldDto(type: 'MdCodeAttribute'); +const _mdList = MixableFieldDto(type: 'MdListAttribute'); +const _mdTable = MixableFieldDto(type: 'MdTableAttribute'); +const _mdDivider = MixableFieldDto(type: 'MdDividerAttribute'); +const _mdBlockQuote = MixableFieldDto(type: 'MdBlockQuoteAttribute'); -class MdDivider extends Spec { +@MixableSpec() +final class MdDivider extends Spec with _$MdDivider { + @MixableProperty(utilities: [MixableUtility(alias: 'height')]) final double? dividerHeight; + @MixableProperty(utilities: [MixableUtility(alias: 'color')]) final Color? dividerColor; + @MixableProperty(utilities: [MixableUtility(alias: 'thickness')]) final double? dividerThickness; const MdDivider({ - required this.dividerHeight, - required this.dividerColor, - required this.dividerThickness, + this.dividerHeight, + this.dividerColor, + this.dividerThickness, }); - - @override - MdDivider lerp( - MdDivider? other, - double t, - ) { - return MdDivider( - dividerHeight: lerpDouble(dividerHeight, other?.dividerHeight, t), - dividerColor: Color.lerp(dividerColor, other?.dividerColor, t), - dividerThickness: - lerpDouble(dividerThickness, other?.dividerThickness, t), - ); - } - - @override - MdDivider copyWith({ - double? dividerHeight, - Color? dividerColor, - double? dividerThickness, - }) { - return MdDivider( - dividerHeight: dividerHeight ?? this.dividerHeight, - dividerColor: dividerColor ?? this.dividerColor, - dividerThickness: dividerThickness ?? this.dividerThickness, - ); - } - - @override - get props => [dividerHeight, dividerColor, dividerThickness]; } -class MdTextStyle extends Spec { +@MixableSpec() +final class MdTextStyle extends Spec with _$MdTextStyle { final TextStyle? textStyle; + final EdgeInsets? padding; const MdTextStyle({ - required this.textStyle, - required this.padding, + this.textStyle, + this.padding, }); - - @override - MdTextStyle lerp( - MdTextStyle? other, - double t, - ) { - return MdTextStyle( - textStyle: TextStyle.lerp(textStyle, other?.textStyle, t), - padding: EdgeInsets.lerp(padding, other?.padding, t), - ); - } - - @override - MdTextStyle copyWith({ - TextStyle? textStyle, - EdgeInsets? padding, - }) { - return MdTextStyle( - textStyle: textStyle ?? this.textStyle, - padding: padding ?? this.padding, - ); - } - - @override - get props => [textStyle, padding]; } -class MdList extends Spec { +@MixableSpec() +final class MdList extends Spec with _$MdList { + @MixableProperty(utilities: [MixableUtility(alias: 'textStyle')]) final TextStyle? list; + @MixableProperty(utilities: [MixableUtility(alias: 'itemTextStyle')]) final TextStyle? listItem; + @MixableProperty(utilities: [MixableUtility(alias: 'itemMarkerTextStyle')]) final TextStyle? listItemMarker; + @MixableProperty( + utilities: [MixableUtility(alias: 'itemMarkerTrailingSpace')]) final double? listItemMarkerTrailingSpace; + @MixableProperty(utilities: [MixableUtility(alias: 'itemMinIndent')]) final double? listItemMinIndent; const MdList({ - required this.list, - required this.listItem, - required this.listItemMarker, - required this.listItemMarkerTrailingSpace, - required this.listItemMinIndent, + this.list, + this.listItem, + this.listItemMarker, + this.listItemMarkerTrailingSpace, + this.listItemMinIndent, }); - - @override - MdList lerp( - MdList? other, - double t, - ) { - return MdList( - list: TextStyle.lerp(list, other?.list, t), - listItem: TextStyle.lerp(listItem, other?.listItem, t), - listItemMarker: TextStyle.lerp(listItemMarker, other?.listItemMarker, t), - listItemMinIndent: - lerpDouble(listItemMinIndent, other?.listItemMinIndent, t), - listItemMarkerTrailingSpace: lerpDouble( - listItemMarkerTrailingSpace, other?.listItemMarkerTrailingSpace, t), - ); - } - - @override - MdList copyWith({ - TextStyle? list, - TextStyle? listItem, - TextStyle? listItemMarker, - double? listItemMinIndent, - double? listItemMarkerTrailingSpace, - }) { - return MdList( - list: list ?? this.list, - listItem: listItem ?? this.listItem, - listItemMinIndent: listItemMinIndent ?? this.listItemMinIndent, - listItemMarker: listItemMarker ?? this.listItemMarker, - listItemMarkerTrailingSpace: - listItemMarkerTrailingSpace ?? this.listItemMarkerTrailingSpace, - ); - } - - @override - get props => [ - list, - listItem, - listItemMarker, - listItemMarkerTrailingSpace, - listItemMinIndent - ]; } -class MdBlockQuote extends Spec { +@MixableSpec() +final class MdBlockQuote extends Spec with _$MdBlockQuote { + @MixableProperty(utilities: [MixableUtility(alias: 'textStyle')]) final TextStyle? blockquote; + @MixableProperty(utilities: [MixableUtility(alias: 'decoration')]) final BoxDecoration? blockquoteDecoration; + @MixableProperty(utilities: [MixableUtility(alias: 'padding')]) final EdgeInsets? blockquotePadding; + @MixableProperty(utilities: [MixableUtility(alias: 'contentPadding')]) final EdgeInsets? blockquoteContentPadding; const MdBlockQuote({ - required this.blockquote, - required this.blockquoteDecoration, - required this.blockquotePadding, - required this.blockquoteContentPadding, + this.blockquote, + this.blockquoteDecoration, + this.blockquotePadding, + this.blockquoteContentPadding, }); - - @override - MdBlockQuote lerp( - MdBlockQuote? other, - double t, - ) { - return MdBlockQuote( - blockquote: TextStyle.lerp(blockquote, other?.blockquote, t), - blockquoteDecoration: BoxDecoration.lerp( - blockquoteDecoration, other?.blockquoteDecoration, t), - blockquotePadding: - EdgeInsets.lerp(blockquotePadding, other?.blockquotePadding, t), - blockquoteContentPadding: EdgeInsets.lerp( - blockquoteContentPadding, other?.blockquoteContentPadding, t), - ); - } - - @override - MdBlockQuote copyWith({ - TextStyle? blockquote, - BoxDecoration? blockquoteDecoration, - EdgeInsets? blockquotePadding, - EdgeInsets? blockquoteContentPadding, - }) { - return MdBlockQuote( - blockquote: blockquote ?? this.blockquote, - blockquoteDecoration: blockquoteDecoration ?? this.blockquoteDecoration, - blockquotePadding: blockquotePadding ?? this.blockquotePadding, - blockquoteContentPadding: - blockquoteContentPadding ?? this.blockquoteContentPadding, - ); - } - - @override - get props => [ - blockquote, - blockquoteDecoration, - blockquotePadding, - blockquoteContentPadding - ]; } -class MdTable extends Spec { +@MixableSpec() +final class MdTable extends Spec with _$MdTable { + @MixableProperty(utilities: [MixableUtility(alias: 'textStyle')]) final TextStyle? table; + @MixableProperty(utilities: [MixableUtility(alias: 'headTextStyle')]) final TextStyle? tableHead; + @MixableProperty(utilities: [MixableUtility(alias: 'bodyTextStyle')]) final TextStyle? tableBody; + @MixableProperty(utilities: [MixableUtility(alias: 'border')]) final TableBorder? tableBorder; + @MixableProperty(utilities: [MixableUtility(alias: 'rowDecoration')]) final BoxDecoration? tableRowDecoration; + @MixableProperty( + utilities: [MixableUtility(alias: 'rowDecorationAlternating')]) final MarkdownAlternating? tableRowDecorationAlternating; + @MixableProperty( + utilities: [ + MixableUtility( + alias: 'cellPadding', + ) + ], + ) final EdgeInsets? tableCellPadding; + @MixableProperty(utilities: [MixableUtility(alias: 'columnWidth')]) final TableColumnWidth? tableColumnWidth; const MdTable({ - required this.table, - required this.tableHead, - required this.tableBody, - required this.tableBorder, - required this.tableRowDecoration, - required this.tableRowDecorationAlternating, - required this.tableCellPadding, - required this.tableColumnWidth, + this.table, + this.tableHead, + this.tableBody, + this.tableBorder, + this.tableRowDecoration, + this.tableRowDecorationAlternating, + this.tableCellPadding, + this.tableColumnWidth, }); - - @override - MdTable lerp( - MdTable? other, - double t, - ) { - return MdTable( - table: TextStyle.lerp(table, other?.table, t), - tableHead: TextStyle.lerp(tableHead, other?.tableHead, t), - tableBody: TextStyle.lerp(tableBody, other?.tableBody, t), - tableBorder: TableBorder.lerp(tableBorder, other?.tableBorder, t), - tableRowDecoration: - BoxDecoration.lerp(tableRowDecoration, other?.tableRowDecoration, t), - tableRowDecorationAlternating: - tableRowDecorationAlternating ?? other?.tableRowDecorationAlternating, - tableCellPadding: - EdgeInsets.lerp(tableCellPadding, other?.tableCellPadding, t), - tableColumnWidth: t < 0.5 ? tableColumnWidth : other?.tableColumnWidth, - ); - } - - @override - MdTable copyWith({ - TextStyle? table, - TextStyle? tableHead, - TextStyle? tableBody, - TableBorder? tableBorder, - BoxDecoration? tableRowDecoration, - MarkdownAlternating? tableRowDecorationAlternating, - EdgeInsets? tableCellPadding, - TableColumnWidth? tableColumnWidth, - }) { - return MdTable( - table: table ?? this.table, - tableHead: tableHead ?? this.tableHead, - tableBody: tableBody ?? this.tableBody, - tableBorder: tableBorder ?? this.tableBorder, - tableRowDecoration: tableRowDecoration ?? this.tableRowDecoration, - tableRowDecorationAlternating: - tableRowDecorationAlternating ?? this.tableRowDecorationAlternating, - tableCellPadding: tableCellPadding ?? this.tableCellPadding, - tableColumnWidth: tableColumnWidth ?? this.tableColumnWidth, - ); - } - - @override - get props => [ - table, - tableHead, - tableBody, - tableBorder, - tableRowDecoration, - tableRowDecorationAlternating, - tableCellPadding, - tableColumnWidth, - ]; } -class MdCode extends Spec { +@MixableSpec() +final class MdCode extends Spec with _$MdCode { + @MixableProperty(utilities: [MixableUtility(alias: 'span')]) final TextStyle? codeSpan; + @MixableProperty(utilities: [ + MixableUtility( + alias: 'padding', + ) + ]) final EdgeInsets? codeblockPadding; + @MixableProperty(utilities: [MixableUtility(alias: 'decoration')]) final BoxDecoration? codeblockDecoration; + @MixableProperty(utilities: [MixableUtility(alias: 'block')]) final TextStyle? codeBlock; final Color? copyIconColor; const MdCode({ - required this.codeSpan, - required this.codeblockPadding, - required this.codeblockDecoration, - required this.copyIconColor, - required this.codeBlock, + this.codeSpan, + this.codeblockPadding, + this.codeblockDecoration, + this.copyIconColor, + this.codeBlock, }); - - @override - MdCode lerp( - MdCode? other, - double t, - ) { - return MdCode( - codeSpan: TextStyle.lerp(codeSpan, other?.codeSpan, t), - codeblockPadding: - EdgeInsets.lerp(codeblockPadding, other?.codeblockPadding, t), - codeblockDecoration: BoxDecoration.lerp( - codeblockDecoration, other?.codeblockDecoration, t), - copyIconColor: Color.lerp(copyIconColor, other?.copyIconColor, t), - codeBlock: TextStyle.lerp(codeBlock, other?.codeBlock, t), - ); - } - - @override - MdCode copyWith({ - TextStyle? codeSpan, - EdgeInsets? codeblockPadding, - BoxDecoration? codeblockDecoration, - Color? copyIconColor, - TextStyle? codeBlock, - }) { - return MdCode( - codeSpan: codeSpan ?? this.codeSpan, - codeblockPadding: codeblockPadding ?? this.codeblockPadding, - codeblockDecoration: codeblockDecoration ?? this.codeblockDecoration, - copyIconColor: copyIconColor ?? this.copyIconColor, - codeBlock: codeBlock ?? this.codeBlock, - ); - } - - @override - get props => [ - codeSpan, - codeblockPadding, - codeblockDecoration, - copyIconColor, - codeBlock - ]; } -class SlideSpec extends Spec { +@MixableSpec() +final class SlideSpec extends Spec with _$SlideSpec { + @MixableProperty(dto: _mdTextStyle, utilities: [MixableUtility(alias: 'h1')]) final MdTextStyle? headline1; + @MixableProperty(dto: _mdTextStyle, utilities: [MixableUtility(alias: 'h2')]) final MdTextStyle? headline2; + @MixableProperty(dto: _mdTextStyle, utilities: [MixableUtility(alias: 'h3')]) final MdTextStyle? headline3; + @MixableProperty(dto: _mdTextStyle, utilities: [MixableUtility(alias: 'h4')]) final MdTextStyle? headline4; + @MixableProperty(dto: _mdTextStyle, utilities: [MixableUtility(alias: 'h5')]) final MdTextStyle? headline5; + @MixableProperty(dto: _mdTextStyle, utilities: [MixableUtility(alias: 'h6')]) final MdTextStyle? headline6; + @MixableProperty(dto: _mdTextStyle) final MdTextStyle? paragraph; final TextStyle? link; final double? blockSpacing; + @MixableProperty(dto: _mdDivider) final MdDivider? divider; + @MixableProperty(dto: _mdBlockQuote) final MdBlockQuote? blockquote; + @MixableProperty(dto: _mdList) final MdList? list; + @MixableProperty(dto: _mdTable) final MdTable? table; + @MixableProperty(dto: _mdCode) final MdCode? code; - final BoxSpec? _innerContainer; - final BoxSpec? _outerContainer; - final BoxSpec? _contentContainer; - final ImageSpec? _image; - - const SlideSpec({ - required this.headline1, - required this.headline2, - required this.headline3, - required this.headline4, - required this.headline5, - required this.headline6, - required this.paragraph, - required this.link, - required this.blockSpacing, - required this.divider, - required this.blockquote, - required this.list, - required this.table, - required this.code, - required BoxSpec? innerContainer, - required BoxSpec? outerContainer, - required BoxSpec? contentContainer, - required ImageSpec? image, - }) : _outerContainer = outerContainer, - _innerContainer = innerContainer, - _contentContainer = contentContainer, - _image = image; - - const SlideSpec.empty() - : headline1 = null, - headline2 = null, - headline3 = null, - headline4 = null, - headline5 = null, - headline6 = null, - paragraph = null, - link = null, - blockSpacing = null, - divider = null, - blockquote = null, - list = null, - table = null, - code = null, - _innerContainer = null, - _outerContainer = null, - _contentContainer = null, - _image = null; - - static SlideSpec of(BuildContext context) { - final mix = MixProvider.of(context); - return fromMix(mix); - } - - static SlideSpec fromMix(MixData mix) { - return mix.specOf(const SlideSpec.empty()); - } - - BoxSpec get innerContainer => _innerContainer ?? const BoxSpec.empty(); + final BoxSpec innerContainer; + final BoxSpec outerContainer; + final BoxSpec contentContainer; + final ImageSpec image; - BoxSpec get outerContainer => _outerContainer ?? const BoxSpec.empty(); + static const of = _$SlideSpec.of; + static const from = _$SlideSpec.from; - BoxSpec get contentContainer => _contentContainer ?? const BoxSpec.empty(); - - ImageSpec get image => _image ?? const ImageSpec.empty(); - - @override - SlideSpec lerp( - SlideSpec? other, - double t, - ) { - if (other == null) return this; - - return SlideSpec( - headline1: headline1?.lerp(other.headline1, t), - headline2: headline2?.lerp(other.headline2, t), - headline3: headline3?.lerp(other.headline3, t), - headline4: headline4?.lerp(other.headline4, t), - headline5: headline5?.lerp(other.headline5, t), - headline6: headline6?.lerp(other.headline6, t), - paragraph: paragraph?.lerp(other.paragraph, t), - link: TextStyle.lerp(link, other.link, t), - blockSpacing: lerpDouble(blockSpacing, other.blockSpacing, t), - divider: divider?.lerp(other.divider, t), - list: list?.lerp(other.list, t), - blockquote: blockquote?.lerp(other.blockquote, t), - table: table?.lerp(other.table, t), - code: code?.lerp(other.code, t), - innerContainer: _innerContainer?.lerp(other._innerContainer, t), - outerContainer: _outerContainer?.lerp(other._outerContainer, t), - contentContainer: _contentContainer?.lerp(other._contentContainer, t), - image: _image?.lerp(other._image, t), - ); - } + const SlideSpec({ + this.headline1, + this.headline2, + this.headline3, + this.headline4, + this.headline5, + this.headline6, + this.paragraph, + this.link, + this.blockSpacing, + this.divider, + this.blockquote, + this.list, + this.table, + this.code, + BoxSpec? innerContainer, + BoxSpec? outerContainer, + BoxSpec? contentContainer, + ImageSpec? image, + super.animated, + }) : outerContainer = outerContainer ?? const BoxSpec(), + innerContainer = innerContainer ?? const BoxSpec(), + contentContainer = contentContainer ?? const BoxSpec(), + image = image ?? const ImageSpec(); MarkdownStyle toStyle() { return MarkdownStyle( @@ -488,72 +253,6 @@ class SlideSpec extends Spec { copyIconColor: code?.copyIconColor ?? Colors.black, ); } - - @override - SlideSpec copyWith({ - TextStyle? textStyle, - MdTextStyle? headline1, - MdTextStyle? headline2, - MdTextStyle? headline3, - MdTextStyle? headline4, - MdTextStyle? headline5, - MdTextStyle? headline6, - MdTextStyle? paragraph, - TextStyle? link, - double? blockSpacing, - MdDivider? divider, - MdList? list, - MdBlockQuote? blockquote, - MdTable? table, - MdCode? code, - BoxSpec? innerContainer, - BoxSpec? outerContainer, - BoxSpec? contentContainer, - ImageSpec? image, - }) { - return SlideSpec( - headline1: headline1 ?? this.headline1, - headline2: headline2 ?? this.headline2, - headline3: headline3 ?? this.headline3, - headline4: headline4 ?? this.headline4, - headline5: headline5 ?? this.headline5, - headline6: headline6 ?? this.headline6, - paragraph: paragraph ?? this.paragraph, - link: link ?? this.link, - blockSpacing: blockSpacing ?? this.blockSpacing, - divider: divider ?? this.divider, - list: list ?? this.list, - blockquote: blockquote ?? this.blockquote, - table: table ?? this.table, - code: code ?? this.code, - innerContainer: innerContainer ?? _innerContainer, - outerContainer: outerContainer ?? _outerContainer, - contentContainer: contentContainer ?? _contentContainer, - image: image ?? _image, - ); - } - - @override - get props => [ - headline1, - headline2, - headline3, - headline4, - headline5, - headline6, - paragraph, - link, - blockSpacing, - divider, - list, - blockquote, - table, - code, - _innerContainer, - _outerContainer, - _contentContainer, - _image, - ]; } extension on MixData { @@ -561,3 +260,55 @@ extension on MixData { return resolvableOf() ?? fallback; } } + +extension SlideSpecUtilityX on SlideSpecUtility { + TextStyleUtility get textStyle { + return TextStyleUtility( + (value) => only( + paragraph: MdTextStyleAttribute(textStyle: value), + headline1: MdTextStyleAttribute(textStyle: value), + headline2: MdTextStyleAttribute(textStyle: value), + headline3: MdTextStyleAttribute(textStyle: value), + headline4: MdTextStyleAttribute(textStyle: value), + headline5: MdTextStyleAttribute(textStyle: value), + headline6: MdTextStyleAttribute(textStyle: value), + list: MdListAttribute(list: value), + table: MdTableAttribute(table: value), + code: MdCodeAttribute(codeBlock: value), + blockquote: MdBlockQuoteAttribute(blockquote: value), + ), + ); + } + + MdTextStyleUtility get headings { + return MdTextStyleUtility( + (value) => only( + headline1: value, + headline2: value, + headline3: value, + headline4: value, + headline5: value, + headline6: value, + ), + ); + } +} + +@MixableEnumUtility(generateCallMethod: false) +class MarkdownAlternatingUtility + extends MixUtility + with _$MarkdownAlternatingUtility { + const MarkdownAlternatingUtility(super.builder); +} + +@MixableClassUtility() +class TableColumnWidthUtility + extends MixUtility with _$TableColumnWidthUtility { + const TableColumnWidthUtility(super.builder); +} + +@MixableClassUtility() +class TableBorderUtility extends MixUtility + with _$TableBorderUtility { + const TableBorderUtility(super.builder); +} diff --git a/lib/styles/style_spec.g.dart b/lib/styles/style_spec.g.dart new file mode 100644 index 0000000..373c55b --- /dev/null +++ b/lib/styles/style_spec.g.dart @@ -0,0 +1,1903 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'style_spec.dart'; + +// ************************************************************************** +// MixableClassUtilityGenerator +// ************************************************************************** + +/// {@template table_column_width_utility} +/// A utility class for creating [Attribute] instances from [TableColumnWidth] values. +/// +/// This class extends [MixUtility] and provides methods to create [Attribute] instances +/// from predefined [TableColumnWidth] values. +/// {@endtemplate} +mixin _$TableColumnWidthUtility + on MixUtility { + /// Creates an [Attribute] instance with the specified TableColumnWidth value. + T call(TableColumnWidth value) => builder(value); +} + +/// {@template table_border_utility} +/// A utility class for creating [Attribute] instances from [TableBorder] values. +/// +/// This class extends [MixUtility] and provides methods to create [Attribute] instances +/// from predefined [TableBorder] values. +/// {@endtemplate} +mixin _$TableBorderUtility on MixUtility { + /// Creates an [Attribute] instance using the [TableBorder.all] constructor. + T all( + {Color color = const Color(0xFF000000), + double width = 1.0, + BorderStyle style = BorderStyle.solid, + BorderRadius borderRadius = BorderRadius.zero}) { + return builder(TableBorder.all( + color: color, width: width, style: style, borderRadius: borderRadius)); + } + + /// Creates an [Attribute] instance using the [TableBorder.symmetric] constructor. + T symmetric( + {BorderSide inside = BorderSide.none, + BorderSide outside = BorderSide.none, + BorderRadius borderRadius = BorderRadius.zero}) { + return builder(TableBorder.symmetric( + inside: inside, outside: outside, borderRadius: borderRadius)); + } + + /// Creates an [Attribute] instance with the specified TableBorder value. + T call(TableBorder value) => builder(value); +} + +// ************************************************************************** +// MixableEnumUtilityGenerator +// ************************************************************************** + +/// {@template markdown_alternating_utility} +/// A utility class for creating [Attribute] instances from [MarkdownAlternating] values. +/// +/// This class extends [MixUtility] and provides methods to create [Attribute] instances +/// from predefined [MarkdownAlternating] values. +/// {@endtemplate} +mixin _$MarkdownAlternatingUtility + on MixUtility { + /// Creates an [Attribute] instance with [MarkdownAlternating.odd] value. + T odd() => builder(MarkdownAlternating.odd); + + /// Creates an [Attribute] instance with [MarkdownAlternating.even] value. + T even() => builder(MarkdownAlternating.even); +} + +// ************************************************************************** +// MixableSpecGenerator +// ************************************************************************** + +// ignore_for_file: deprecated_member_use_from_same_package + +base mixin _$MdDivider on Spec { + static MdDivider from(MixData mix) { + return mix.attributeOf()?.resolve(mix) ?? + const MdDivider(); + } + + /// {@template md_divider_of} + /// Retrieves the [MdDivider] from the nearest [Mix] ancestor in the widget tree. + /// + /// This method uses [Mix.of] to obtain the [Mix] instance associated with the + /// given [BuildContext], and then retrieves the [MdDivider] from that [Mix]. + /// If no ancestor [Mix] is found, this method returns an empty [MdDivider]. + /// + /// Example: + /// + /// ```dart + /// final mdDivider = MdDivider.of(context); + /// ``` + /// {@endtemplate} + static MdDivider of(BuildContext context) { + return _$MdDivider.from(Mix.of(context)); + } + + /// Creates a copy of this [MdDivider] but with the given fields + /// replaced with the new values. + @override + MdDivider copyWith({ + double? dividerHeight, + Color? dividerColor, + double? dividerThickness, + }) { + return MdDivider( + dividerHeight: dividerHeight ?? _$this.dividerHeight, + dividerColor: dividerColor ?? _$this.dividerColor, + dividerThickness: dividerThickness ?? _$this.dividerThickness, + ); + } + + /// Linearly interpolates between this [MdDivider] and another [MdDivider] based on the given parameter [t]. + /// + /// The parameter [t] represents the interpolation factor, typically ranging from 0.0 to 1.0. + /// When [t] is 0.0, the current [MdDivider] is returned. When [t] is 1.0, the [other] [MdDivider] is returned. + /// For values of [t] between 0.0 and 1.0, an interpolated [MdDivider] is returned. + /// + /// If [other] is null, this method returns the current [MdDivider] instance. + /// + /// The interpolation is performed on each property of the [MdDivider] using the appropriate + /// interpolation method: + /// + /// - [MixHelpers.lerpDouble] for [dividerHeight] and [dividerThickness]. + /// - [Color.lerp] for [dividerColor]. + + /// For , the interpolation is performed using a step function. + /// If [t] is less than 0.5, the value from the current [MdDivider] is used. Otherwise, the value + /// from the [other] [MdDivider] is used. + /// + /// This method is typically used in animations to smoothly transition between + /// different [MdDivider] configurations. + @override + MdDivider lerp(MdDivider? other, double t) { + if (other == null) return _$this; + + return MdDivider( + dividerHeight: + MixHelpers.lerpDouble(_$this.dividerHeight, other.dividerHeight, t), + dividerColor: Color.lerp(_$this.dividerColor, other.dividerColor, t), + dividerThickness: MixHelpers.lerpDouble( + _$this.dividerThickness, other.dividerThickness, t), + ); + } + + /// The list of properties that constitute the state of this [MdDivider]. + /// + /// This property is used by the [==] operator and the [hashCode] getter to + /// compare two [MdDivider] instances for equality. + @override + List get props => [ + _$this.dividerHeight, + _$this.dividerColor, + _$this.dividerThickness, + ]; + + MdDivider get _$this => this as MdDivider; +} + +/// Represents the attributes of a [MdDivider]. +/// +/// This class encapsulates properties defining the layout and +/// appearance of a [MdDivider]. +/// +/// Use this class to configure the attributes of a [MdDivider] and pass it to +/// the [MdDivider] constructor. +final class MdDividerAttribute extends SpecAttribute { + final double? dividerHeight; + final ColorDto? dividerColor; + final double? dividerThickness; + + const MdDividerAttribute({ + this.dividerHeight, + this.dividerColor, + this.dividerThickness, + }); + + /// Resolves to [MdDivider] using the provided [MixData]. + /// + /// If a property is null in the [MixData], it falls back to the + /// default value defined in the `defaultValue` for that property. + /// + /// ```dart + /// final mdDivider = MdDividerAttribute(...).resolve(mix); + /// ``` + @override + MdDivider resolve(MixData mix) { + return MdDivider( + dividerHeight: dividerHeight, + dividerColor: dividerColor?.resolve(mix), + dividerThickness: dividerThickness, + ); + } + + /// Merges the properties of this [MdDividerAttribute] with the properties of [other]. + /// + /// If [other] is null, returns this instance unchanged. Otherwise, returns a new + /// [MdDividerAttribute] with the properties of [other] taking precedence over + /// the corresponding properties of this instance. + /// + /// Properties from [other] that are null will fall back + /// to the values from this instance. + @override + MdDividerAttribute merge(MdDividerAttribute? other) { + if (other == null) return this; + + return MdDividerAttribute( + dividerHeight: other.dividerHeight ?? dividerHeight, + dividerColor: + dividerColor?.merge(other.dividerColor) ?? other.dividerColor, + dividerThickness: other.dividerThickness ?? dividerThickness, + ); + } + + /// The list of properties that constitute the state of this [MdDividerAttribute]. + /// + /// This property is used by the [==] operator and the [hashCode] getter to + /// compare two [MdDividerAttribute] instances for equality. + @override + List get props => [ + dividerHeight, + dividerColor, + dividerThickness, + ]; +} + +/// Utility class for configuring [MdDividerAttribute] properties. +/// +/// This class provides methods to set individual properties of a [MdDividerAttribute]. +/// Use the methods of this class to configure specific properties of a [MdDividerAttribute]. +base class MdDividerUtility + extends SpecUtility { + /// Utility for defining [MdDividerAttribute.dividerHeight] + late final height = DoubleUtility((v) => only(dividerHeight: v)); + + /// Utility for defining [MdDividerAttribute.dividerColor] + late final color = ColorUtility((v) => only(dividerColor: v)); + + /// Utility for defining [MdDividerAttribute.dividerThickness] + late final thickness = DoubleUtility((v) => only(dividerThickness: v)); + + MdDividerUtility(super.builder); + + static final self = MdDividerUtility((v) => v); + + /// Returns a new [MdDividerAttribute] with the specified properties. + @override + T only({ + double? dividerHeight, + ColorDto? dividerColor, + double? dividerThickness, + }) { + return builder(MdDividerAttribute( + dividerHeight: dividerHeight, + dividerColor: dividerColor, + dividerThickness: dividerThickness, + )); + } +} + +/// A tween that interpolates between two [MdDivider] instances. +/// +/// This class can be used in animations to smoothly transition between +/// different [MdDivider] specifications. +class MdDividerTween extends Tween { + MdDividerTween({ + super.begin, + super.end, + }); + + @override + MdDivider lerp(double t) { + if (begin == null && end == null) return const MdDivider(); + if (begin == null) return end!; + + return begin!.lerp(end!, t); + } +} + +// ignore_for_file: deprecated_member_use_from_same_package + +base mixin _$MdTextStyle on Spec { + static MdTextStyle from(MixData mix) { + return mix.attributeOf()?.resolve(mix) ?? + const MdTextStyle(); + } + + /// {@template md_text_style_of} + /// Retrieves the [MdTextStyle] from the nearest [Mix] ancestor in the widget tree. + /// + /// This method uses [Mix.of] to obtain the [Mix] instance associated with the + /// given [BuildContext], and then retrieves the [MdTextStyle] from that [Mix]. + /// If no ancestor [Mix] is found, this method returns an empty [MdTextStyle]. + /// + /// Example: + /// + /// ```dart + /// final mdTextStyle = MdTextStyle.of(context); + /// ``` + /// {@endtemplate} + static MdTextStyle of(BuildContext context) { + return _$MdTextStyle.from(Mix.of(context)); + } + + /// Creates a copy of this [MdTextStyle] but with the given fields + /// replaced with the new values. + @override + MdTextStyle copyWith({ + TextStyle? textStyle, + EdgeInsets? padding, + }) { + return MdTextStyle( + textStyle: textStyle ?? _$this.textStyle, + padding: padding ?? _$this.padding, + ); + } + + /// Linearly interpolates between this [MdTextStyle] and another [MdTextStyle] based on the given parameter [t]. + /// + /// The parameter [t] represents the interpolation factor, typically ranging from 0.0 to 1.0. + /// When [t] is 0.0, the current [MdTextStyle] is returned. When [t] is 1.0, the [other] [MdTextStyle] is returned. + /// For values of [t] between 0.0 and 1.0, an interpolated [MdTextStyle] is returned. + /// + /// If [other] is null, this method returns the current [MdTextStyle] instance. + /// + /// The interpolation is performed on each property of the [MdTextStyle] using the appropriate + /// interpolation method: + /// + /// - [MixHelpers.lerpTextStyle] for [textStyle]. + /// - [EdgeInsets.lerp] for [padding]. + + /// For , the interpolation is performed using a step function. + /// If [t] is less than 0.5, the value from the current [MdTextStyle] is used. Otherwise, the value + /// from the [other] [MdTextStyle] is used. + /// + /// This method is typically used in animations to smoothly transition between + /// different [MdTextStyle] configurations. + @override + MdTextStyle lerp(MdTextStyle? other, double t) { + if (other == null) return _$this; + + return MdTextStyle( + textStyle: MixHelpers.lerpTextStyle(_$this.textStyle, other.textStyle, t), + padding: EdgeInsets.lerp(_$this.padding, other.padding, t), + ); + } + + /// The list of properties that constitute the state of this [MdTextStyle]. + /// + /// This property is used by the [==] operator and the [hashCode] getter to + /// compare two [MdTextStyle] instances for equality. + @override + List get props => [ + _$this.textStyle, + _$this.padding, + ]; + + MdTextStyle get _$this => this as MdTextStyle; +} + +/// Represents the attributes of a [MdTextStyle]. +/// +/// This class encapsulates properties defining the layout and +/// appearance of a [MdTextStyle]. +/// +/// Use this class to configure the attributes of a [MdTextStyle] and pass it to +/// the [MdTextStyle] constructor. +final class MdTextStyleAttribute extends SpecAttribute { + final TextStyleDto? textStyle; + final EdgeInsetsDto? padding; + + const MdTextStyleAttribute({ + this.textStyle, + this.padding, + }); + + /// Resolves to [MdTextStyle] using the provided [MixData]. + /// + /// If a property is null in the [MixData], it falls back to the + /// default value defined in the `defaultValue` for that property. + /// + /// ```dart + /// final mdTextStyle = MdTextStyleAttribute(...).resolve(mix); + /// ``` + @override + MdTextStyle resolve(MixData mix) { + return MdTextStyle( + textStyle: textStyle?.resolve(mix), + padding: padding?.resolve(mix), + ); + } + + /// Merges the properties of this [MdTextStyleAttribute] with the properties of [other]. + /// + /// If [other] is null, returns this instance unchanged. Otherwise, returns a new + /// [MdTextStyleAttribute] with the properties of [other] taking precedence over + /// the corresponding properties of this instance. + /// + /// Properties from [other] that are null will fall back + /// to the values from this instance. + @override + MdTextStyleAttribute merge(MdTextStyleAttribute? other) { + if (other == null) return this; + + return MdTextStyleAttribute( + textStyle: textStyle?.merge(other.textStyle) ?? other.textStyle, + padding: padding?.merge(other.padding) ?? other.padding, + ); + } + + /// The list of properties that constitute the state of this [MdTextStyleAttribute]. + /// + /// This property is used by the [==] operator and the [hashCode] getter to + /// compare two [MdTextStyleAttribute] instances for equality. + @override + List get props => [ + textStyle, + padding, + ]; +} + +/// Utility class for configuring [MdTextStyleAttribute] properties. +/// +/// This class provides methods to set individual properties of a [MdTextStyleAttribute]. +/// Use the methods of this class to configure specific properties of a [MdTextStyleAttribute]. +base class MdTextStyleUtility + extends SpecUtility { + /// Utility for defining [MdTextStyleAttribute.textStyle] + late final textStyle = TextStyleUtility((v) => only(textStyle: v)); + + /// Utility for defining [MdTextStyleAttribute.padding] + late final padding = EdgeInsetsUtility((v) => only(padding: v)); + + MdTextStyleUtility(super.builder); + + static final self = MdTextStyleUtility((v) => v); + + /// Returns a new [MdTextStyleAttribute] with the specified properties. + @override + T only({ + TextStyleDto? textStyle, + EdgeInsetsDto? padding, + }) { + return builder(MdTextStyleAttribute( + textStyle: textStyle, + padding: padding, + )); + } +} + +/// A tween that interpolates between two [MdTextStyle] instances. +/// +/// This class can be used in animations to smoothly transition between +/// different [MdTextStyle] specifications. +class MdTextStyleTween extends Tween { + MdTextStyleTween({ + super.begin, + super.end, + }); + + @override + MdTextStyle lerp(double t) { + if (begin == null && end == null) return const MdTextStyle(); + if (begin == null) return end!; + + return begin!.lerp(end!, t); + } +} + +// ignore_for_file: deprecated_member_use_from_same_package + +base mixin _$MdList on Spec { + static MdList from(MixData mix) { + return mix.attributeOf()?.resolve(mix) ?? const MdList(); + } + + /// {@template md_list_of} + /// Retrieves the [MdList] from the nearest [Mix] ancestor in the widget tree. + /// + /// This method uses [Mix.of] to obtain the [Mix] instance associated with the + /// given [BuildContext], and then retrieves the [MdList] from that [Mix]. + /// If no ancestor [Mix] is found, this method returns an empty [MdList]. + /// + /// Example: + /// + /// ```dart + /// final mdList = MdList.of(context); + /// ``` + /// {@endtemplate} + static MdList of(BuildContext context) { + return _$MdList.from(Mix.of(context)); + } + + /// Creates a copy of this [MdList] but with the given fields + /// replaced with the new values. + @override + MdList copyWith({ + TextStyle? list, + TextStyle? listItem, + TextStyle? listItemMarker, + double? listItemMarkerTrailingSpace, + double? listItemMinIndent, + }) { + return MdList( + list: list ?? _$this.list, + listItem: listItem ?? _$this.listItem, + listItemMarker: listItemMarker ?? _$this.listItemMarker, + listItemMarkerTrailingSpace: + listItemMarkerTrailingSpace ?? _$this.listItemMarkerTrailingSpace, + listItemMinIndent: listItemMinIndent ?? _$this.listItemMinIndent, + ); + } + + /// Linearly interpolates between this [MdList] and another [MdList] based on the given parameter [t]. + /// + /// The parameter [t] represents the interpolation factor, typically ranging from 0.0 to 1.0. + /// When [t] is 0.0, the current [MdList] is returned. When [t] is 1.0, the [other] [MdList] is returned. + /// For values of [t] between 0.0 and 1.0, an interpolated [MdList] is returned. + /// + /// If [other] is null, this method returns the current [MdList] instance. + /// + /// The interpolation is performed on each property of the [MdList] using the appropriate + /// interpolation method: + /// + /// - [MixHelpers.lerpTextStyle] for [list] and [listItem] and [listItemMarker]. + /// - [MixHelpers.lerpDouble] for [listItemMarkerTrailingSpace] and [listItemMinIndent]. + + /// For , the interpolation is performed using a step function. + /// If [t] is less than 0.5, the value from the current [MdList] is used. Otherwise, the value + /// from the [other] [MdList] is used. + /// + /// This method is typically used in animations to smoothly transition between + /// different [MdList] configurations. + @override + MdList lerp(MdList? other, double t) { + if (other == null) return _$this; + + return MdList( + list: MixHelpers.lerpTextStyle(_$this.list, other.list, t), + listItem: MixHelpers.lerpTextStyle(_$this.listItem, other.listItem, t), + listItemMarker: MixHelpers.lerpTextStyle( + _$this.listItemMarker, other.listItemMarker, t), + listItemMarkerTrailingSpace: MixHelpers.lerpDouble( + _$this.listItemMarkerTrailingSpace, + other.listItemMarkerTrailingSpace, + t), + listItemMinIndent: MixHelpers.lerpDouble( + _$this.listItemMinIndent, other.listItemMinIndent, t), + ); + } + + /// The list of properties that constitute the state of this [MdList]. + /// + /// This property is used by the [==] operator and the [hashCode] getter to + /// compare two [MdList] instances for equality. + @override + List get props => [ + _$this.list, + _$this.listItem, + _$this.listItemMarker, + _$this.listItemMarkerTrailingSpace, + _$this.listItemMinIndent, + ]; + + MdList get _$this => this as MdList; +} + +/// Represents the attributes of a [MdList]. +/// +/// This class encapsulates properties defining the layout and +/// appearance of a [MdList]. +/// +/// Use this class to configure the attributes of a [MdList] and pass it to +/// the [MdList] constructor. +final class MdListAttribute extends SpecAttribute { + final TextStyleDto? list; + final TextStyleDto? listItem; + final TextStyleDto? listItemMarker; + final double? listItemMarkerTrailingSpace; + final double? listItemMinIndent; + + const MdListAttribute({ + this.list, + this.listItem, + this.listItemMarker, + this.listItemMarkerTrailingSpace, + this.listItemMinIndent, + }); + + /// Resolves to [MdList] using the provided [MixData]. + /// + /// If a property is null in the [MixData], it falls back to the + /// default value defined in the `defaultValue` for that property. + /// + /// ```dart + /// final mdList = MdListAttribute(...).resolve(mix); + /// ``` + @override + MdList resolve(MixData mix) { + return MdList( + list: list?.resolve(mix), + listItem: listItem?.resolve(mix), + listItemMarker: listItemMarker?.resolve(mix), + listItemMarkerTrailingSpace: listItemMarkerTrailingSpace, + listItemMinIndent: listItemMinIndent, + ); + } + + /// Merges the properties of this [MdListAttribute] with the properties of [other]. + /// + /// If [other] is null, returns this instance unchanged. Otherwise, returns a new + /// [MdListAttribute] with the properties of [other] taking precedence over + /// the corresponding properties of this instance. + /// + /// Properties from [other] that are null will fall back + /// to the values from this instance. + @override + MdListAttribute merge(MdListAttribute? other) { + if (other == null) return this; + + return MdListAttribute( + list: list?.merge(other.list) ?? other.list, + listItem: listItem?.merge(other.listItem) ?? other.listItem, + listItemMarker: + listItemMarker?.merge(other.listItemMarker) ?? other.listItemMarker, + listItemMarkerTrailingSpace: + other.listItemMarkerTrailingSpace ?? listItemMarkerTrailingSpace, + listItemMinIndent: other.listItemMinIndent ?? listItemMinIndent, + ); + } + + /// The list of properties that constitute the state of this [MdListAttribute]. + /// + /// This property is used by the [==] operator and the [hashCode] getter to + /// compare two [MdListAttribute] instances for equality. + @override + List get props => [ + list, + listItem, + listItemMarker, + listItemMarkerTrailingSpace, + listItemMinIndent, + ]; +} + +/// Utility class for configuring [MdListAttribute] properties. +/// +/// This class provides methods to set individual properties of a [MdListAttribute]. +/// Use the methods of this class to configure specific properties of a [MdListAttribute]. +base class MdListUtility + extends SpecUtility { + /// Utility for defining [MdListAttribute.list] + late final textStyle = TextStyleUtility((v) => only(list: v)); + + /// Utility for defining [MdListAttribute.listItem] + late final itemTextStyle = TextStyleUtility((v) => only(listItem: v)); + + /// Utility for defining [MdListAttribute.listItemMarker] + late final itemMarkerTextStyle = + TextStyleUtility((v) => only(listItemMarker: v)); + + /// Utility for defining [MdListAttribute.listItemMarkerTrailingSpace] + late final itemMarkerTrailingSpace = + DoubleUtility((v) => only(listItemMarkerTrailingSpace: v)); + + /// Utility for defining [MdListAttribute.listItemMinIndent] + late final itemMinIndent = DoubleUtility((v) => only(listItemMinIndent: v)); + + MdListUtility(super.builder); + + static final self = MdListUtility((v) => v); + + /// Returns a new [MdListAttribute] with the specified properties. + @override + T only({ + TextStyleDto? list, + TextStyleDto? listItem, + TextStyleDto? listItemMarker, + double? listItemMarkerTrailingSpace, + double? listItemMinIndent, + }) { + return builder(MdListAttribute( + list: list, + listItem: listItem, + listItemMarker: listItemMarker, + listItemMarkerTrailingSpace: listItemMarkerTrailingSpace, + listItemMinIndent: listItemMinIndent, + )); + } +} + +/// A tween that interpolates between two [MdList] instances. +/// +/// This class can be used in animations to smoothly transition between +/// different [MdList] specifications. +class MdListTween extends Tween { + MdListTween({ + super.begin, + super.end, + }); + + @override + MdList lerp(double t) { + if (begin == null && end == null) return const MdList(); + if (begin == null) return end!; + + return begin!.lerp(end!, t); + } +} + +// ignore_for_file: deprecated_member_use_from_same_package + +base mixin _$MdBlockQuote on Spec { + static MdBlockQuote from(MixData mix) { + return mix.attributeOf()?.resolve(mix) ?? + const MdBlockQuote(); + } + + /// {@template md_block_quote_of} + /// Retrieves the [MdBlockQuote] from the nearest [Mix] ancestor in the widget tree. + /// + /// This method uses [Mix.of] to obtain the [Mix] instance associated with the + /// given [BuildContext], and then retrieves the [MdBlockQuote] from that [Mix]. + /// If no ancestor [Mix] is found, this method returns an empty [MdBlockQuote]. + /// + /// Example: + /// + /// ```dart + /// final mdBlockQuote = MdBlockQuote.of(context); + /// ``` + /// {@endtemplate} + static MdBlockQuote of(BuildContext context) { + return _$MdBlockQuote.from(Mix.of(context)); + } + + /// Creates a copy of this [MdBlockQuote] but with the given fields + /// replaced with the new values. + @override + MdBlockQuote copyWith({ + TextStyle? blockquote, + BoxDecoration? blockquoteDecoration, + EdgeInsets? blockquotePadding, + EdgeInsets? blockquoteContentPadding, + }) { + return MdBlockQuote( + blockquote: blockquote ?? _$this.blockquote, + blockquoteDecoration: blockquoteDecoration ?? _$this.blockquoteDecoration, + blockquotePadding: blockquotePadding ?? _$this.blockquotePadding, + blockquoteContentPadding: + blockquoteContentPadding ?? _$this.blockquoteContentPadding, + ); + } + + /// Linearly interpolates between this [MdBlockQuote] and another [MdBlockQuote] based on the given parameter [t]. + /// + /// The parameter [t] represents the interpolation factor, typically ranging from 0.0 to 1.0. + /// When [t] is 0.0, the current [MdBlockQuote] is returned. When [t] is 1.0, the [other] [MdBlockQuote] is returned. + /// For values of [t] between 0.0 and 1.0, an interpolated [MdBlockQuote] is returned. + /// + /// If [other] is null, this method returns the current [MdBlockQuote] instance. + /// + /// The interpolation is performed on each property of the [MdBlockQuote] using the appropriate + /// interpolation method: + /// + /// - [MixHelpers.lerpTextStyle] for [blockquote]. + /// - [BoxDecoration.lerp] for [blockquoteDecoration]. + /// - [EdgeInsets.lerp] for [blockquotePadding] and [blockquoteContentPadding]. + + /// For , the interpolation is performed using a step function. + /// If [t] is less than 0.5, the value from the current [MdBlockQuote] is used. Otherwise, the value + /// from the [other] [MdBlockQuote] is used. + /// + /// This method is typically used in animations to smoothly transition between + /// different [MdBlockQuote] configurations. + @override + MdBlockQuote lerp(MdBlockQuote? other, double t) { + if (other == null) return _$this; + + return MdBlockQuote( + blockquote: + MixHelpers.lerpTextStyle(_$this.blockquote, other.blockquote, t), + blockquoteDecoration: BoxDecoration.lerp( + _$this.blockquoteDecoration, other.blockquoteDecoration, t), + blockquotePadding: + EdgeInsets.lerp(_$this.blockquotePadding, other.blockquotePadding, t), + blockquoteContentPadding: EdgeInsets.lerp( + _$this.blockquoteContentPadding, other.blockquoteContentPadding, t), + ); + } + + /// The list of properties that constitute the state of this [MdBlockQuote]. + /// + /// This property is used by the [==] operator and the [hashCode] getter to + /// compare two [MdBlockQuote] instances for equality. + @override + List get props => [ + _$this.blockquote, + _$this.blockquoteDecoration, + _$this.blockquotePadding, + _$this.blockquoteContentPadding, + ]; + + MdBlockQuote get _$this => this as MdBlockQuote; +} + +/// Represents the attributes of a [MdBlockQuote]. +/// +/// This class encapsulates properties defining the layout and +/// appearance of a [MdBlockQuote]. +/// +/// Use this class to configure the attributes of a [MdBlockQuote] and pass it to +/// the [MdBlockQuote] constructor. +final class MdBlockQuoteAttribute extends SpecAttribute { + final TextStyleDto? blockquote; + final BoxDecorationDto? blockquoteDecoration; + final EdgeInsetsDto? blockquotePadding; + final EdgeInsetsDto? blockquoteContentPadding; + + const MdBlockQuoteAttribute({ + this.blockquote, + this.blockquoteDecoration, + this.blockquotePadding, + this.blockquoteContentPadding, + }); + + /// Resolves to [MdBlockQuote] using the provided [MixData]. + /// + /// If a property is null in the [MixData], it falls back to the + /// default value defined in the `defaultValue` for that property. + /// + /// ```dart + /// final mdBlockQuote = MdBlockQuoteAttribute(...).resolve(mix); + /// ``` + @override + MdBlockQuote resolve(MixData mix) { + return MdBlockQuote( + blockquote: blockquote?.resolve(mix), + blockquoteDecoration: blockquoteDecoration?.resolve(mix), + blockquotePadding: blockquotePadding?.resolve(mix), + blockquoteContentPadding: blockquoteContentPadding?.resolve(mix), + ); + } + + /// Merges the properties of this [MdBlockQuoteAttribute] with the properties of [other]. + /// + /// If [other] is null, returns this instance unchanged. Otherwise, returns a new + /// [MdBlockQuoteAttribute] with the properties of [other] taking precedence over + /// the corresponding properties of this instance. + /// + /// Properties from [other] that are null will fall back + /// to the values from this instance. + @override + MdBlockQuoteAttribute merge(MdBlockQuoteAttribute? other) { + if (other == null) return this; + + return MdBlockQuoteAttribute( + blockquote: blockquote?.merge(other.blockquote) ?? other.blockquote, + blockquoteDecoration: + blockquoteDecoration?.merge(other.blockquoteDecoration) ?? + other.blockquoteDecoration, + blockquotePadding: blockquotePadding?.merge(other.blockquotePadding) ?? + other.blockquotePadding, + blockquoteContentPadding: + blockquoteContentPadding?.merge(other.blockquoteContentPadding) ?? + other.blockquoteContentPadding, + ); + } + + /// The list of properties that constitute the state of this [MdBlockQuoteAttribute]. + /// + /// This property is used by the [==] operator and the [hashCode] getter to + /// compare two [MdBlockQuoteAttribute] instances for equality. + @override + List get props => [ + blockquote, + blockquoteDecoration, + blockquotePadding, + blockquoteContentPadding, + ]; +} + +/// Utility class for configuring [MdBlockQuoteAttribute] properties. +/// +/// This class provides methods to set individual properties of a [MdBlockQuoteAttribute]. +/// Use the methods of this class to configure specific properties of a [MdBlockQuoteAttribute]. +base class MdBlockQuoteUtility + extends SpecUtility { + /// Utility for defining [MdBlockQuoteAttribute.blockquote] + late final textStyle = TextStyleUtility((v) => only(blockquote: v)); + + /// Utility for defining [MdBlockQuoteAttribute.blockquoteDecoration] + late final decoration = + BoxDecorationUtility((v) => only(blockquoteDecoration: v)); + + /// Utility for defining [MdBlockQuoteAttribute.blockquotePadding] + late final padding = EdgeInsetsUtility((v) => only(blockquotePadding: v)); + + /// Utility for defining [MdBlockQuoteAttribute.blockquoteContentPadding] + late final contentPadding = + EdgeInsetsUtility((v) => only(blockquoteContentPadding: v)); + + MdBlockQuoteUtility(super.builder); + + static final self = MdBlockQuoteUtility((v) => v); + + /// Returns a new [MdBlockQuoteAttribute] with the specified properties. + @override + T only({ + TextStyleDto? blockquote, + BoxDecorationDto? blockquoteDecoration, + EdgeInsetsDto? blockquotePadding, + EdgeInsetsDto? blockquoteContentPadding, + }) { + return builder(MdBlockQuoteAttribute( + blockquote: blockquote, + blockquoteDecoration: blockquoteDecoration, + blockquotePadding: blockquotePadding, + blockquoteContentPadding: blockquoteContentPadding, + )); + } +} + +/// A tween that interpolates between two [MdBlockQuote] instances. +/// +/// This class can be used in animations to smoothly transition between +/// different [MdBlockQuote] specifications. +class MdBlockQuoteTween extends Tween { + MdBlockQuoteTween({ + super.begin, + super.end, + }); + + @override + MdBlockQuote lerp(double t) { + if (begin == null && end == null) return const MdBlockQuote(); + if (begin == null) return end!; + + return begin!.lerp(end!, t); + } +} + +// ignore_for_file: deprecated_member_use_from_same_package + +base mixin _$MdTable on Spec { + static MdTable from(MixData mix) { + return mix.attributeOf()?.resolve(mix) ?? const MdTable(); + } + + /// {@template md_table_of} + /// Retrieves the [MdTable] from the nearest [Mix] ancestor in the widget tree. + /// + /// This method uses [Mix.of] to obtain the [Mix] instance associated with the + /// given [BuildContext], and then retrieves the [MdTable] from that [Mix]. + /// If no ancestor [Mix] is found, this method returns an empty [MdTable]. + /// + /// Example: + /// + /// ```dart + /// final mdTable = MdTable.of(context); + /// ``` + /// {@endtemplate} + static MdTable of(BuildContext context) { + return _$MdTable.from(Mix.of(context)); + } + + /// Creates a copy of this [MdTable] but with the given fields + /// replaced with the new values. + @override + MdTable copyWith({ + TextStyle? table, + TextStyle? tableHead, + TextStyle? tableBody, + TableBorder? tableBorder, + BoxDecoration? tableRowDecoration, + MarkdownAlternating? tableRowDecorationAlternating, + EdgeInsets? tableCellPadding, + TableColumnWidth? tableColumnWidth, + }) { + return MdTable( + table: table ?? _$this.table, + tableHead: tableHead ?? _$this.tableHead, + tableBody: tableBody ?? _$this.tableBody, + tableBorder: tableBorder ?? _$this.tableBorder, + tableRowDecoration: tableRowDecoration ?? _$this.tableRowDecoration, + tableRowDecorationAlternating: + tableRowDecorationAlternating ?? _$this.tableRowDecorationAlternating, + tableCellPadding: tableCellPadding ?? _$this.tableCellPadding, + tableColumnWidth: tableColumnWidth ?? _$this.tableColumnWidth, + ); + } + + /// Linearly interpolates between this [MdTable] and another [MdTable] based on the given parameter [t]. + /// + /// The parameter [t] represents the interpolation factor, typically ranging from 0.0 to 1.0. + /// When [t] is 0.0, the current [MdTable] is returned. When [t] is 1.0, the [other] [MdTable] is returned. + /// For values of [t] between 0.0 and 1.0, an interpolated [MdTable] is returned. + /// + /// If [other] is null, this method returns the current [MdTable] instance. + /// + /// The interpolation is performed on each property of the [MdTable] using the appropriate + /// interpolation method: + /// + /// - [MixHelpers.lerpTextStyle] for [table] and [tableHead] and [tableBody]. + /// - [TableBorder.lerp] for [tableBorder]. + /// - [BoxDecoration.lerp] for [tableRowDecoration]. + /// - [EdgeInsets.lerp] for [tableCellPadding]. + + /// For [tableRowDecorationAlternating] and [tableColumnWidth], the interpolation is performed using a step function. + /// If [t] is less than 0.5, the value from the current [MdTable] is used. Otherwise, the value + /// from the [other] [MdTable] is used. + /// + /// This method is typically used in animations to smoothly transition between + /// different [MdTable] configurations. + @override + MdTable lerp(MdTable? other, double t) { + if (other == null) return _$this; + + return MdTable( + table: MixHelpers.lerpTextStyle(_$this.table, other.table, t), + tableHead: MixHelpers.lerpTextStyle(_$this.tableHead, other.tableHead, t), + tableBody: MixHelpers.lerpTextStyle(_$this.tableBody, other.tableBody, t), + tableBorder: TableBorder.lerp(_$this.tableBorder, other.tableBorder, t), + tableRowDecoration: BoxDecoration.lerp( + _$this.tableRowDecoration, other.tableRowDecoration, t), + tableRowDecorationAlternating: t < 0.5 + ? _$this.tableRowDecorationAlternating + : other.tableRowDecorationAlternating, + tableCellPadding: + EdgeInsets.lerp(_$this.tableCellPadding, other.tableCellPadding, t), + tableColumnWidth: + t < 0.5 ? _$this.tableColumnWidth : other.tableColumnWidth, + ); + } + + /// The list of properties that constitute the state of this [MdTable]. + /// + /// This property is used by the [==] operator and the [hashCode] getter to + /// compare two [MdTable] instances for equality. + @override + List get props => [ + _$this.table, + _$this.tableHead, + _$this.tableBody, + _$this.tableBorder, + _$this.tableRowDecoration, + _$this.tableRowDecorationAlternating, + _$this.tableCellPadding, + _$this.tableColumnWidth, + ]; + + MdTable get _$this => this as MdTable; +} + +/// Represents the attributes of a [MdTable]. +/// +/// This class encapsulates properties defining the layout and +/// appearance of a [MdTable]. +/// +/// Use this class to configure the attributes of a [MdTable] and pass it to +/// the [MdTable] constructor. +final class MdTableAttribute extends SpecAttribute { + final TextStyleDto? table; + final TextStyleDto? tableHead; + final TextStyleDto? tableBody; + final TableBorder? tableBorder; + final BoxDecorationDto? tableRowDecoration; + final MarkdownAlternating? tableRowDecorationAlternating; + final EdgeInsetsDto? tableCellPadding; + final TableColumnWidth? tableColumnWidth; + + const MdTableAttribute({ + this.table, + this.tableHead, + this.tableBody, + this.tableBorder, + this.tableRowDecoration, + this.tableRowDecorationAlternating, + this.tableCellPadding, + this.tableColumnWidth, + }); + + /// Resolves to [MdTable] using the provided [MixData]. + /// + /// If a property is null in the [MixData], it falls back to the + /// default value defined in the `defaultValue` for that property. + /// + /// ```dart + /// final mdTable = MdTableAttribute(...).resolve(mix); + /// ``` + @override + MdTable resolve(MixData mix) { + return MdTable( + table: table?.resolve(mix), + tableHead: tableHead?.resolve(mix), + tableBody: tableBody?.resolve(mix), + tableBorder: tableBorder, + tableRowDecoration: tableRowDecoration?.resolve(mix), + tableRowDecorationAlternating: tableRowDecorationAlternating, + tableCellPadding: tableCellPadding?.resolve(mix), + tableColumnWidth: tableColumnWidth, + ); + } + + /// Merges the properties of this [MdTableAttribute] with the properties of [other]. + /// + /// If [other] is null, returns this instance unchanged. Otherwise, returns a new + /// [MdTableAttribute] with the properties of [other] taking precedence over + /// the corresponding properties of this instance. + /// + /// Properties from [other] that are null will fall back + /// to the values from this instance. + @override + MdTableAttribute merge(MdTableAttribute? other) { + if (other == null) return this; + + return MdTableAttribute( + table: table?.merge(other.table) ?? other.table, + tableHead: tableHead?.merge(other.tableHead) ?? other.tableHead, + tableBody: tableBody?.merge(other.tableBody) ?? other.tableBody, + tableBorder: other.tableBorder ?? tableBorder, + tableRowDecoration: tableRowDecoration?.merge(other.tableRowDecoration) ?? + other.tableRowDecoration, + tableRowDecorationAlternating: + other.tableRowDecorationAlternating ?? tableRowDecorationAlternating, + tableCellPadding: tableCellPadding?.merge(other.tableCellPadding) ?? + other.tableCellPadding, + tableColumnWidth: other.tableColumnWidth ?? tableColumnWidth, + ); + } + + /// The list of properties that constitute the state of this [MdTableAttribute]. + /// + /// This property is used by the [==] operator and the [hashCode] getter to + /// compare two [MdTableAttribute] instances for equality. + @override + List get props => [ + table, + tableHead, + tableBody, + tableBorder, + tableRowDecoration, + tableRowDecorationAlternating, + tableCellPadding, + tableColumnWidth, + ]; +} + +/// Utility class for configuring [MdTableAttribute] properties. +/// +/// This class provides methods to set individual properties of a [MdTableAttribute]. +/// Use the methods of this class to configure specific properties of a [MdTableAttribute]. +base class MdTableUtility + extends SpecUtility { + /// Utility for defining [MdTableAttribute.table] + late final textStyle = TextStyleUtility((v) => only(table: v)); + + /// Utility for defining [MdTableAttribute.tableHead] + late final headTextStyle = TextStyleUtility((v) => only(tableHead: v)); + + /// Utility for defining [MdTableAttribute.tableBody] + late final bodyTextStyle = TextStyleUtility((v) => only(tableBody: v)); + + /// Utility for defining [MdTableAttribute.tableBorder] + late final border = TableBorderUtility((v) => only(tableBorder: v)); + + /// Utility for defining [MdTableAttribute.tableRowDecoration] + late final rowDecoration = + BoxDecorationUtility((v) => only(tableRowDecoration: v)); + + /// Utility for defining [MdTableAttribute.tableRowDecorationAlternating] + late final rowDecorationAlternating = + MarkdownAlternatingUtility((v) => only(tableRowDecorationAlternating: v)); + + /// Utility for defining [MdTableAttribute.tableCellPadding] + late final cellPadding = EdgeInsetsUtility((v) => only(tableCellPadding: v)); + + /// Utility for defining [MdTableAttribute.tableColumnWidth] + late final columnWidth = + TableColumnWidthUtility((v) => only(tableColumnWidth: v)); + + MdTableUtility(super.builder); + + static final self = MdTableUtility((v) => v); + + /// Returns a new [MdTableAttribute] with the specified properties. + @override + T only({ + TextStyleDto? table, + TextStyleDto? tableHead, + TextStyleDto? tableBody, + TableBorder? tableBorder, + BoxDecorationDto? tableRowDecoration, + MarkdownAlternating? tableRowDecorationAlternating, + EdgeInsetsDto? tableCellPadding, + TableColumnWidth? tableColumnWidth, + }) { + return builder(MdTableAttribute( + table: table, + tableHead: tableHead, + tableBody: tableBody, + tableBorder: tableBorder, + tableRowDecoration: tableRowDecoration, + tableRowDecorationAlternating: tableRowDecorationAlternating, + tableCellPadding: tableCellPadding, + tableColumnWidth: tableColumnWidth, + )); + } +} + +/// A tween that interpolates between two [MdTable] instances. +/// +/// This class can be used in animations to smoothly transition between +/// different [MdTable] specifications. +class MdTableTween extends Tween { + MdTableTween({ + super.begin, + super.end, + }); + + @override + MdTable lerp(double t) { + if (begin == null && end == null) return const MdTable(); + if (begin == null) return end!; + + return begin!.lerp(end!, t); + } +} + +// ignore_for_file: deprecated_member_use_from_same_package + +base mixin _$MdCode on Spec { + static MdCode from(MixData mix) { + return mix.attributeOf()?.resolve(mix) ?? const MdCode(); + } + + /// {@template md_code_of} + /// Retrieves the [MdCode] from the nearest [Mix] ancestor in the widget tree. + /// + /// This method uses [Mix.of] to obtain the [Mix] instance associated with the + /// given [BuildContext], and then retrieves the [MdCode] from that [Mix]. + /// If no ancestor [Mix] is found, this method returns an empty [MdCode]. + /// + /// Example: + /// + /// ```dart + /// final mdCode = MdCode.of(context); + /// ``` + /// {@endtemplate} + static MdCode of(BuildContext context) { + return _$MdCode.from(Mix.of(context)); + } + + /// Creates a copy of this [MdCode] but with the given fields + /// replaced with the new values. + @override + MdCode copyWith({ + TextStyle? codeSpan, + EdgeInsets? codeblockPadding, + BoxDecoration? codeblockDecoration, + Color? copyIconColor, + TextStyle? codeBlock, + }) { + return MdCode( + codeSpan: codeSpan ?? _$this.codeSpan, + codeblockPadding: codeblockPadding ?? _$this.codeblockPadding, + codeblockDecoration: codeblockDecoration ?? _$this.codeblockDecoration, + copyIconColor: copyIconColor ?? _$this.copyIconColor, + codeBlock: codeBlock ?? _$this.codeBlock, + ); + } + + /// Linearly interpolates between this [MdCode] and another [MdCode] based on the given parameter [t]. + /// + /// The parameter [t] represents the interpolation factor, typically ranging from 0.0 to 1.0. + /// When [t] is 0.0, the current [MdCode] is returned. When [t] is 1.0, the [other] [MdCode] is returned. + /// For values of [t] between 0.0 and 1.0, an interpolated [MdCode] is returned. + /// + /// If [other] is null, this method returns the current [MdCode] instance. + /// + /// The interpolation is performed on each property of the [MdCode] using the appropriate + /// interpolation method: + /// + /// - [MixHelpers.lerpTextStyle] for [codeSpan] and [codeBlock]. + /// - [EdgeInsets.lerp] for [codeblockPadding]. + /// - [BoxDecoration.lerp] for [codeblockDecoration]. + /// - [Color.lerp] for [copyIconColor]. + + /// For , the interpolation is performed using a step function. + /// If [t] is less than 0.5, the value from the current [MdCode] is used. Otherwise, the value + /// from the [other] [MdCode] is used. + /// + /// This method is typically used in animations to smoothly transition between + /// different [MdCode] configurations. + @override + MdCode lerp(MdCode? other, double t) { + if (other == null) return _$this; + + return MdCode( + codeSpan: MixHelpers.lerpTextStyle(_$this.codeSpan, other.codeSpan, t), + codeblockPadding: + EdgeInsets.lerp(_$this.codeblockPadding, other.codeblockPadding, t), + codeblockDecoration: BoxDecoration.lerp( + _$this.codeblockDecoration, other.codeblockDecoration, t), + copyIconColor: Color.lerp(_$this.copyIconColor, other.copyIconColor, t), + codeBlock: MixHelpers.lerpTextStyle(_$this.codeBlock, other.codeBlock, t), + ); + } + + /// The list of properties that constitute the state of this [MdCode]. + /// + /// This property is used by the [==] operator and the [hashCode] getter to + /// compare two [MdCode] instances for equality. + @override + List get props => [ + _$this.codeSpan, + _$this.codeblockPadding, + _$this.codeblockDecoration, + _$this.copyIconColor, + _$this.codeBlock, + ]; + + MdCode get _$this => this as MdCode; +} + +/// Represents the attributes of a [MdCode]. +/// +/// This class encapsulates properties defining the layout and +/// appearance of a [MdCode]. +/// +/// Use this class to configure the attributes of a [MdCode] and pass it to +/// the [MdCode] constructor. +final class MdCodeAttribute extends SpecAttribute { + final TextStyleDto? codeSpan; + final EdgeInsetsDto? codeblockPadding; + final BoxDecorationDto? codeblockDecoration; + final ColorDto? copyIconColor; + final TextStyleDto? codeBlock; + + const MdCodeAttribute({ + this.codeSpan, + this.codeblockPadding, + this.codeblockDecoration, + this.copyIconColor, + this.codeBlock, + }); + + /// Resolves to [MdCode] using the provided [MixData]. + /// + /// If a property is null in the [MixData], it falls back to the + /// default value defined in the `defaultValue` for that property. + /// + /// ```dart + /// final mdCode = MdCodeAttribute(...).resolve(mix); + /// ``` + @override + MdCode resolve(MixData mix) { + return MdCode( + codeSpan: codeSpan?.resolve(mix), + codeblockPadding: codeblockPadding?.resolve(mix), + codeblockDecoration: codeblockDecoration?.resolve(mix), + copyIconColor: copyIconColor?.resolve(mix), + codeBlock: codeBlock?.resolve(mix), + ); + } + + /// Merges the properties of this [MdCodeAttribute] with the properties of [other]. + /// + /// If [other] is null, returns this instance unchanged. Otherwise, returns a new + /// [MdCodeAttribute] with the properties of [other] taking precedence over + /// the corresponding properties of this instance. + /// + /// Properties from [other] that are null will fall back + /// to the values from this instance. + @override + MdCodeAttribute merge(MdCodeAttribute? other) { + if (other == null) return this; + + return MdCodeAttribute( + codeSpan: codeSpan?.merge(other.codeSpan) ?? other.codeSpan, + codeblockPadding: codeblockPadding?.merge(other.codeblockPadding) ?? + other.codeblockPadding, + codeblockDecoration: + codeblockDecoration?.merge(other.codeblockDecoration) ?? + other.codeblockDecoration, + copyIconColor: + copyIconColor?.merge(other.copyIconColor) ?? other.copyIconColor, + codeBlock: codeBlock?.merge(other.codeBlock) ?? other.codeBlock, + ); + } + + /// The list of properties that constitute the state of this [MdCodeAttribute]. + /// + /// This property is used by the [==] operator and the [hashCode] getter to + /// compare two [MdCodeAttribute] instances for equality. + @override + List get props => [ + codeSpan, + codeblockPadding, + codeblockDecoration, + copyIconColor, + codeBlock, + ]; +} + +/// Utility class for configuring [MdCodeAttribute] properties. +/// +/// This class provides methods to set individual properties of a [MdCodeAttribute]. +/// Use the methods of this class to configure specific properties of a [MdCodeAttribute]. +base class MdCodeUtility + extends SpecUtility { + /// Utility for defining [MdCodeAttribute.codeSpan] + late final span = TextStyleUtility((v) => only(codeSpan: v)); + + /// Utility for defining [MdCodeAttribute.codeblockPadding] + late final padding = EdgeInsetsUtility((v) => only(codeblockPadding: v)); + + /// Utility for defining [MdCodeAttribute.codeblockDecoration] + late final decoration = + BoxDecorationUtility((v) => only(codeblockDecoration: v)); + + /// Utility for defining [MdCodeAttribute.copyIconColor] + late final copyIconColor = ColorUtility((v) => only(copyIconColor: v)); + + /// Utility for defining [MdCodeAttribute.codeBlock] + late final block = TextStyleUtility((v) => only(codeBlock: v)); + + MdCodeUtility(super.builder); + + static final self = MdCodeUtility((v) => v); + + /// Returns a new [MdCodeAttribute] with the specified properties. + @override + T only({ + TextStyleDto? codeSpan, + EdgeInsetsDto? codeblockPadding, + BoxDecorationDto? codeblockDecoration, + ColorDto? copyIconColor, + TextStyleDto? codeBlock, + }) { + return builder(MdCodeAttribute( + codeSpan: codeSpan, + codeblockPadding: codeblockPadding, + codeblockDecoration: codeblockDecoration, + copyIconColor: copyIconColor, + codeBlock: codeBlock, + )); + } +} + +/// A tween that interpolates between two [MdCode] instances. +/// +/// This class can be used in animations to smoothly transition between +/// different [MdCode] specifications. +class MdCodeTween extends Tween { + MdCodeTween({ + super.begin, + super.end, + }); + + @override + MdCode lerp(double t) { + if (begin == null && end == null) return const MdCode(); + if (begin == null) return end!; + + return begin!.lerp(end!, t); + } +} + +// ignore_for_file: deprecated_member_use_from_same_package + +base mixin _$SlideSpec on Spec { + static SlideSpec from(MixData mix) { + return mix.attributeOf()?.resolve(mix) ?? + const SlideSpec(); + } + + /// {@template slide_spec_of} + /// Retrieves the [SlideSpec] from the nearest [Mix] ancestor in the widget tree. + /// + /// This method uses [Mix.of] to obtain the [Mix] instance associated with the + /// given [BuildContext], and then retrieves the [SlideSpec] from that [Mix]. + /// If no ancestor [Mix] is found, this method returns an empty [SlideSpec]. + /// + /// Example: + /// + /// ```dart + /// final slideSpec = SlideSpec.of(context); + /// ``` + /// {@endtemplate} + static SlideSpec of(BuildContext context) { + return _$SlideSpec.from(Mix.of(context)); + } + + /// Creates a copy of this [SlideSpec] but with the given fields + /// replaced with the new values. + @override + SlideSpec copyWith({ + MdTextStyle? headline1, + MdTextStyle? headline2, + MdTextStyle? headline3, + MdTextStyle? headline4, + MdTextStyle? headline5, + MdTextStyle? headline6, + MdTextStyle? paragraph, + TextStyle? link, + double? blockSpacing, + MdDivider? divider, + MdBlockQuote? blockquote, + MdList? list, + MdTable? table, + MdCode? code, + BoxSpec? innerContainer, + BoxSpec? outerContainer, + BoxSpec? contentContainer, + ImageSpec? image, + AnimatedData? animated, + }) { + return SlideSpec( + headline1: headline1 ?? _$this.headline1, + headline2: headline2 ?? _$this.headline2, + headline3: headline3 ?? _$this.headline3, + headline4: headline4 ?? _$this.headline4, + headline5: headline5 ?? _$this.headline5, + headline6: headline6 ?? _$this.headline6, + paragraph: paragraph ?? _$this.paragraph, + link: link ?? _$this.link, + blockSpacing: blockSpacing ?? _$this.blockSpacing, + divider: divider ?? _$this.divider, + blockquote: blockquote ?? _$this.blockquote, + list: list ?? _$this.list, + table: table ?? _$this.table, + code: code ?? _$this.code, + innerContainer: innerContainer ?? _$this.innerContainer, + outerContainer: outerContainer ?? _$this.outerContainer, + contentContainer: contentContainer ?? _$this.contentContainer, + image: image ?? _$this.image, + animated: animated ?? _$this.animated, + ); + } + + /// Linearly interpolates between this [SlideSpec] and another [SlideSpec] based on the given parameter [t]. + /// + /// The parameter [t] represents the interpolation factor, typically ranging from 0.0 to 1.0. + /// When [t] is 0.0, the current [SlideSpec] is returned. When [t] is 1.0, the [other] [SlideSpec] is returned. + /// For values of [t] between 0.0 and 1.0, an interpolated [SlideSpec] is returned. + /// + /// If [other] is null, this method returns the current [SlideSpec] instance. + /// + /// The interpolation is performed on each property of the [SlideSpec] using the appropriate + /// interpolation method: + /// + /// - [MixHelpers.lerpTextStyle] for [link]. + /// - [MixHelpers.lerpDouble] for [blockSpacing]. + /// - [BoxSpec.lerp] for [innerContainer] and [outerContainer] and [contentContainer]. + /// - [ImageSpec.lerp] for [image]. + + /// For [headline1] and [headline2] and [headline3] and [headline4] and [headline5] and [headline6] and [paragraph] and [divider] and [blockquote] and [list] and [table] and [code] and [animated], the interpolation is performed using a step function. + /// If [t] is less than 0.5, the value from the current [SlideSpec] is used. Otherwise, the value + /// from the [other] [SlideSpec] is used. + /// + /// This method is typically used in animations to smoothly transition between + /// different [SlideSpec] configurations. + @override + SlideSpec lerp(SlideSpec? other, double t) { + if (other == null) return _$this; + + return SlideSpec( + headline1: _$this.headline1?.lerp(other.headline1, t) ?? other.headline1, + headline2: _$this.headline2?.lerp(other.headline2, t) ?? other.headline2, + headline3: _$this.headline3?.lerp(other.headline3, t) ?? other.headline3, + headline4: _$this.headline4?.lerp(other.headline4, t) ?? other.headline4, + headline5: _$this.headline5?.lerp(other.headline5, t) ?? other.headline5, + headline6: _$this.headline6?.lerp(other.headline6, t) ?? other.headline6, + paragraph: _$this.paragraph?.lerp(other.paragraph, t) ?? other.paragraph, + link: MixHelpers.lerpTextStyle(_$this.link, other.link, t), + blockSpacing: + MixHelpers.lerpDouble(_$this.blockSpacing, other.blockSpacing, t), + divider: _$this.divider?.lerp(other.divider, t) ?? other.divider, + blockquote: + _$this.blockquote?.lerp(other.blockquote, t) ?? other.blockquote, + list: _$this.list?.lerp(other.list, t) ?? other.list, + table: _$this.table?.lerp(other.table, t) ?? other.table, + code: _$this.code?.lerp(other.code, t) ?? other.code, + innerContainer: _$this.innerContainer.lerp(other.innerContainer, t), + outerContainer: _$this.outerContainer.lerp(other.outerContainer, t), + contentContainer: _$this.contentContainer.lerp(other.contentContainer, t), + image: _$this.image.lerp(other.image, t), + animated: t < 0.5 ? _$this.animated : other.animated, + ); + } + + /// The list of properties that constitute the state of this [SlideSpec]. + /// + /// This property is used by the [==] operator and the [hashCode] getter to + /// compare two [SlideSpec] instances for equality. + @override + List get props => [ + _$this.headline1, + _$this.headline2, + _$this.headline3, + _$this.headline4, + _$this.headline5, + _$this.headline6, + _$this.paragraph, + _$this.link, + _$this.blockSpacing, + _$this.divider, + _$this.blockquote, + _$this.list, + _$this.table, + _$this.code, + _$this.innerContainer, + _$this.outerContainer, + _$this.contentContainer, + _$this.image, + _$this.animated, + ]; + + SlideSpec get _$this => this as SlideSpec; +} + +/// Represents the attributes of a [SlideSpec]. +/// +/// This class encapsulates properties defining the layout and +/// appearance of a [SlideSpec]. +/// +/// Use this class to configure the attributes of a [SlideSpec] and pass it to +/// the [SlideSpec] constructor. +final class SlideSpecAttribute extends SpecAttribute { + final MdTextStyleAttribute? headline1; + final MdTextStyleAttribute? headline2; + final MdTextStyleAttribute? headline3; + final MdTextStyleAttribute? headline4; + final MdTextStyleAttribute? headline5; + final MdTextStyleAttribute? headline6; + final MdTextStyleAttribute? paragraph; + final TextStyleDto? link; + final double? blockSpacing; + final MdDividerAttribute? divider; + final MdBlockQuoteAttribute? blockquote; + final MdListAttribute? list; + final MdTableAttribute? table; + final MdCodeAttribute? code; + final BoxSpecAttribute? innerContainer; + final BoxSpecAttribute? outerContainer; + final BoxSpecAttribute? contentContainer; + final ImageSpecAttribute? image; + + const SlideSpecAttribute({ + this.headline1, + this.headline2, + this.headline3, + this.headline4, + this.headline5, + this.headline6, + this.paragraph, + this.link, + this.blockSpacing, + this.divider, + this.blockquote, + this.list, + this.table, + this.code, + this.innerContainer, + this.outerContainer, + this.contentContainer, + this.image, + super.animated, + }); + + /// Resolves to [SlideSpec] using the provided [MixData]. + /// + /// If a property is null in the [MixData], it falls back to the + /// default value defined in the `defaultValue` for that property. + /// + /// ```dart + /// final slideSpec = SlideSpecAttribute(...).resolve(mix); + /// ``` + @override + SlideSpec resolve(MixData mix) { + return SlideSpec( + headline1: headline1?.resolve(mix), + headline2: headline2?.resolve(mix), + headline3: headline3?.resolve(mix), + headline4: headline4?.resolve(mix), + headline5: headline5?.resolve(mix), + headline6: headline6?.resolve(mix), + paragraph: paragraph?.resolve(mix), + link: link?.resolve(mix), + blockSpacing: blockSpacing, + divider: divider?.resolve(mix), + blockquote: blockquote?.resolve(mix), + list: list?.resolve(mix), + table: table?.resolve(mix), + code: code?.resolve(mix), + innerContainer: innerContainer?.resolve(mix), + outerContainer: outerContainer?.resolve(mix), + contentContainer: contentContainer?.resolve(mix), + image: image?.resolve(mix), + animated: animated?.resolve(mix) ?? mix.animation, + ); + } + + /// Merges the properties of this [SlideSpecAttribute] with the properties of [other]. + /// + /// If [other] is null, returns this instance unchanged. Otherwise, returns a new + /// [SlideSpecAttribute] with the properties of [other] taking precedence over + /// the corresponding properties of this instance. + /// + /// Properties from [other] that are null will fall back + /// to the values from this instance. + @override + SlideSpecAttribute merge(SlideSpecAttribute? other) { + if (other == null) return this; + + return SlideSpecAttribute( + headline1: headline1?.merge(other.headline1) ?? other.headline1, + headline2: headline2?.merge(other.headline2) ?? other.headline2, + headline3: headline3?.merge(other.headline3) ?? other.headline3, + headline4: headline4?.merge(other.headline4) ?? other.headline4, + headline5: headline5?.merge(other.headline5) ?? other.headline5, + headline6: headline6?.merge(other.headline6) ?? other.headline6, + paragraph: paragraph?.merge(other.paragraph) ?? other.paragraph, + link: link?.merge(other.link) ?? other.link, + blockSpacing: other.blockSpacing ?? blockSpacing, + divider: divider?.merge(other.divider) ?? other.divider, + blockquote: blockquote?.merge(other.blockquote) ?? other.blockquote, + list: list?.merge(other.list) ?? other.list, + table: table?.merge(other.table) ?? other.table, + code: code?.merge(other.code) ?? other.code, + innerContainer: + innerContainer?.merge(other.innerContainer) ?? other.innerContainer, + outerContainer: + outerContainer?.merge(other.outerContainer) ?? other.outerContainer, + contentContainer: contentContainer?.merge(other.contentContainer) ?? + other.contentContainer, + image: image?.merge(other.image) ?? other.image, + animated: animated?.merge(other.animated) ?? other.animated, + ); + } + + /// The list of properties that constitute the state of this [SlideSpecAttribute]. + /// + /// This property is used by the [==] operator and the [hashCode] getter to + /// compare two [SlideSpecAttribute] instances for equality. + @override + List get props => [ + headline1, + headline2, + headline3, + headline4, + headline5, + headline6, + paragraph, + link, + blockSpacing, + divider, + blockquote, + list, + table, + code, + innerContainer, + outerContainer, + contentContainer, + image, + animated, + ]; +} + +/// Utility class for configuring [SlideSpecAttribute] properties. +/// +/// This class provides methods to set individual properties of a [SlideSpecAttribute]. +/// Use the methods of this class to configure specific properties of a [SlideSpecAttribute]. +base class SlideSpecUtility + extends SpecUtility { + /// Utility for defining [SlideSpecAttribute.headline1] + late final h1 = MdTextStyleUtility((v) => only(headline1: v)); + + /// Utility for defining [SlideSpecAttribute.headline2] + late final h2 = MdTextStyleUtility((v) => only(headline2: v)); + + /// Utility for defining [SlideSpecAttribute.headline3] + late final h3 = MdTextStyleUtility((v) => only(headline3: v)); + + /// Utility for defining [SlideSpecAttribute.headline4] + late final h4 = MdTextStyleUtility((v) => only(headline4: v)); + + /// Utility for defining [SlideSpecAttribute.headline5] + late final h5 = MdTextStyleUtility((v) => only(headline5: v)); + + /// Utility for defining [SlideSpecAttribute.headline6] + late final h6 = MdTextStyleUtility((v) => only(headline6: v)); + + /// Utility for defining [SlideSpecAttribute.paragraph] + late final paragraph = MdTextStyleUtility((v) => only(paragraph: v)); + + /// Utility for defining [SlideSpecAttribute.link] + late final link = TextStyleUtility((v) => only(link: v)); + + /// Utility for defining [SlideSpecAttribute.blockSpacing] + late final blockSpacing = DoubleUtility((v) => only(blockSpacing: v)); + + /// Utility for defining [SlideSpecAttribute.divider] + late final divider = MdDividerUtility((v) => only(divider: v)); + + /// Utility for defining [SlideSpecAttribute.blockquote] + late final blockquote = MdBlockQuoteUtility((v) => only(blockquote: v)); + + /// Utility for defining [SlideSpecAttribute.list] + late final list = MdListUtility((v) => only(list: v)); + + /// Utility for defining [SlideSpecAttribute.table] + late final table = MdTableUtility((v) => only(table: v)); + + /// Utility for defining [SlideSpecAttribute.code] + late final code = MdCodeUtility((v) => only(code: v)); + + /// Utility for defining [SlideSpecAttribute.innerContainer] + late final innerContainer = BoxSpecUtility((v) => only(innerContainer: v)); + + /// Utility for defining [SlideSpecAttribute.outerContainer] + late final outerContainer = BoxSpecUtility((v) => only(outerContainer: v)); + + /// Utility for defining [SlideSpecAttribute.contentContainer] + late final contentContainer = + BoxSpecUtility((v) => only(contentContainer: v)); + + /// Utility for defining [SlideSpecAttribute.image] + late final image = ImageSpecUtility((v) => only(image: v)); + + /// Utility for defining [SlideSpecAttribute.animated] + late final animated = AnimatedUtility((v) => only(animated: v)); + + SlideSpecUtility(super.builder); + + static final self = SlideSpecUtility((v) => v); + + /// Returns a new [SlideSpecAttribute] with the specified properties. + @override + T only({ + MdTextStyleAttribute? headline1, + MdTextStyleAttribute? headline2, + MdTextStyleAttribute? headline3, + MdTextStyleAttribute? headline4, + MdTextStyleAttribute? headline5, + MdTextStyleAttribute? headline6, + MdTextStyleAttribute? paragraph, + TextStyleDto? link, + double? blockSpacing, + MdDividerAttribute? divider, + MdBlockQuoteAttribute? blockquote, + MdListAttribute? list, + MdTableAttribute? table, + MdCodeAttribute? code, + BoxSpecAttribute? innerContainer, + BoxSpecAttribute? outerContainer, + BoxSpecAttribute? contentContainer, + ImageSpecAttribute? image, + AnimatedDataDto? animated, + }) { + return builder(SlideSpecAttribute( + headline1: headline1, + headline2: headline2, + headline3: headline3, + headline4: headline4, + headline5: headline5, + headline6: headline6, + paragraph: paragraph, + link: link, + blockSpacing: blockSpacing, + divider: divider, + blockquote: blockquote, + list: list, + table: table, + code: code, + innerContainer: innerContainer, + outerContainer: outerContainer, + contentContainer: contentContainer, + image: image, + animated: animated, + )); + } +} + +/// A tween that interpolates between two [SlideSpec] instances. +/// +/// This class can be used in animations to smoothly transition between +/// different [SlideSpec] specifications. +class SlideSpecTween extends Tween { + SlideSpecTween({ + super.begin, + super.end, + }); + + @override + SlideSpec lerp(double t) { + if (begin == null && end == null) return const SlideSpec(); + if (begin == null) return end!; + + return begin!.lerp(end!, t); + } +} diff --git a/lib/styles/style_util.dart b/lib/styles/style_util.dart index ee9d8ba..1510eef 100644 --- a/lib/styles/style_util.dart +++ b/lib/styles/style_util.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:markdown_viewer/markdown_viewer.dart'; import '../superdeck.dart'; @@ -14,577 +13,74 @@ TextStyle get serifTextStyle => baseTextStyle.copyWith(fontSize: 50); TextStyle get headingTextStyle => baseTextStyle.copyWith(height: 1.2); +final _util = SlideSpecUtility.self; +final _h1 = _util.h1; +final _h2 = _util.h2; +final _h3 = _util.h3; +final _h4 = _util.h4; +final _h5 = _util.h5; +final _h6 = _util.h6; +final _headings = _util.headings; +final _paragraph = _util.paragraph; +final _link = _util.link; +final _list = _util.list; +final _table = _util.table; +final _code = _util.code; +final _blockquote = _util.blockquote; +final _divider = _util.divider; +final _image = _util.image; +final _outerContainer = _util.outerContainer; +final _contentContainer = _util.contentContainer; +final _blockSpacing = _util.blockSpacing; +final _textStyle = _util.textStyle; + Style get defaultStyle => Style.create([ - $deck.outerContainer.color.black(), + _outerContainer.color.black(), // $.innerContainer.color.transparent(), - $deck.contentContainer.padding.all(40), + _contentContainer.padding.all(40), // $.contentContainer.color(Colors.yellow), - $deck.textStyle.as(baseTextStyle), - $deck.headings.textStyle.as(headingTextStyle), - $deck.h1.textStyle.fontSize(96), - $deck.h1.padding.bottom(12), - $deck.h2.textStyle.fontSize(72), - $deck.h2.padding.bottom(9), - $deck.h3.textStyle.fontSize(48), - $deck.h3.padding.bottom(6), - $deck.h4.textStyle.fontSize(36), - $deck.h4.padding.bottom(4), - $deck.h5.textStyle.fontSize(24), - $deck.h5.padding.bottom(3), - $deck.h6.textStyle.as(baseTextStyle), - $deck.h6.padding.bottom(3), - $deck.paragraph.textStyle.as(baseTextStyle), - $deck.paragraph.padding.bottom(12), - $deck.link.color(Colors.blue), - $deck.list.textStyle.as(baseTextStyle), - $deck.list.item.as(baseTextStyle), - $deck.list.itemMarker.as(baseTextStyle), - $deck.list.itemMarkerTrailingSpace(12), - $deck.list.itemMinIndent(12), - $deck.table.textStyle.as(baseTextStyle), - $deck.table.head.as(baseTextStyle.copyWith(fontWeight: FontWeight.bold)), - $deck.table.body.as(baseTextStyle), - $deck.blockSpacing(20), - $deck.table.cellPadding.all(12), - $deck.table.border.all(color: Colors.grey, width: 2), - $deck.table.rowDecoration.color(Colors.grey.withOpacity(0.1)), - $deck.code.span.as(monoTextStyle), - $deck.code.padding.all(24), - $deck.code.decoration.color(const Color.fromARGB(255, 23, 23, 23)), - $deck.code.decoration.borderRadius.circular(10), - $deck.blockquote.textStyle.as(serifTextStyle), - $deck.blockquote.textStyle.fontSize(32), - $deck.blockquote.padding.bottom(12), - $deck.blockquote.contentPadding.left(30), - $deck.blockquote.decoration.border.left.color(Colors.grey), - $deck.blockquote.decoration.border.left.width(4), - $deck.divider.height(1), - $deck.divider.color(Colors.grey), - $deck.divider.thickness(2), - $deck.image.fit.cover(), + _textStyle.as(baseTextStyle), + _headings.textStyle.as(headingTextStyle), + _h1.textStyle.fontSize(96), + _h1.padding.bottom(12), + _h2.textStyle.fontSize(72), + _h2.padding.bottom(9), + _h3.textStyle.fontSize(48), + _h3.padding.bottom(6), + _h4.textStyle.fontSize(36), + _h4.padding.bottom(4), + _h5.textStyle.fontSize(24), + _h5.padding.bottom(3), + _h6.textStyle.as(baseTextStyle), + _h6.padding.bottom(3), + _paragraph.textStyle.as(baseTextStyle), + _paragraph.padding.bottom(12), + _link.color(const Color.fromARGB(255, 66, 82, 96)), + _list.textStyle.as(baseTextStyle), + _list.itemTextStyle.as(baseTextStyle), + _list.itemMarkerTextStyle.as(baseTextStyle), + _list.itemMarkerTrailingSpace(12), + _list.itemMinIndent(12), + _table.textStyle.as(baseTextStyle), + _table.headTextStyle + .as(baseTextStyle.copyWith(fontWeight: FontWeight.bold)), + _table.bodyTextStyle.as(baseTextStyle), + _blockSpacing(20), + _table.cellPadding.all(12), + _table.border.all(color: Colors.grey, width: 2), + _table.rowDecoration.color(Colors.grey.withOpacity(0.1)), + _code.span.as(monoTextStyle), + _code.padding.all(24), + _code.decoration.color(const Color.fromARGB(255, 23, 23, 23)), + _code.decoration.borderRadius.circular(10), + _blockquote.textStyle.as(serifTextStyle), + _blockquote.textStyle.fontSize(32), + _blockquote.padding.bottom(12), + _blockquote.contentPadding.left(30), + _blockquote.decoration.border.left.color(Colors.grey), + _blockquote.decoration.border.left.width(4), + _divider.height(1), + _divider.color(Colors.grey), + _divider.thickness(2), + _image.fit.cover(), ]); - -const $deck = SlideStyleUtility(MixUtility.selfBuilder); - -SlideStyleUtility styleSlide() { - return const SlideStyleUtility(MixUtility.selfBuilder); -} - -class SlideStyleUtility - extends SpecUtility { - const SlideStyleUtility(super.builder); - - TextStyleUtility get textStyle { - return TextStyleUtility( - (value) => only( - paragraph: MdTextStyleDto(textStyle: value), - headline1: MdTextStyleDto(textStyle: value), - headline2: MdTextStyleDto(textStyle: value), - headline3: MdTextStyleDto(textStyle: value), - headline4: MdTextStyleDto(textStyle: value), - headline5: MdTextStyleDto(textStyle: value), - headline6: MdTextStyleDto(textStyle: value), - list: MdListDto(textStyle: value), - table: MdTableDto(textStyle: value), - code: MdCodeDto(textStyle: value), - blockquote: MdBlockQuoteDto(textStyle: value), - ), - ); - } - - MdTextStyleUtil get headings { - return MdTextStyleUtil( - (value) => only( - headline1: value, - headline2: value, - headline3: value, - headline4: value, - headline5: value, - headline6: value, - ), - ); - } - - MdDividerUtil get divider { - return MdDividerUtil( - (value) => only(divider: value), - ); - } - - MdTextStyleUtil get h1 { - return MdTextStyleUtil( - (value) => only(headline1: value), - ); - } - - BoxSpecUtility get innerContainer { - return BoxSpecUtility( - (value) => only(innerContainer: value), - ); - } - - BoxSpecUtility get outerContainer { - return BoxSpecUtility( - (value) => only(outerContainer: value), - ); - } - - BoxSpecUtility get contentContainer { - return BoxSpecUtility( - (value) => only(contentContainer: value), - ); - } - - ImageSpecUtility get image { - return ImageSpecUtility( - (value) => only(image: value), - ); - } - - MdTextStyleUtil get h2 { - return MdTextStyleUtil( - (value) => only(headline2: value), - ); - } - - MdTextStyleUtil get h3 { - return MdTextStyleUtil( - (value) => only(headline3: value), - ); - } - - MdTextStyleUtil get h4 { - return MdTextStyleUtil( - (value) => only(headline4: value), - ); - } - - MdTextStyleUtil get h5 { - return MdTextStyleUtil( - (value) => only(headline5: value), - ); - } - - MdTextStyleUtil get h6 { - return MdTextStyleUtil( - (value) => only(headline6: value), - ); - } - - MdTextStyleUtil get paragraph { - return MdTextStyleUtil( - (value) => only(paragraph: value), - ); - } - - TextStyleUtility get link { - return TextStyleUtility( - (value) => only(link: value), - ); - } - - MdListUtil get list { - return MdListUtil( - (value) => only(list: value), - ); - } - - MdTableUtil get table { - return MdTableUtil( - (value) => only(table: value), - ); - } - - MdCodeUtil get code { - return MdCodeUtil( - (value) => only(code: value), - ); - } - - MdBlockQuoteUtil get blockquote { - return MdBlockQuoteUtil( - (value) => only(blockquote: value), - ); - } - - DoubleUtility get blockSpacing { - return DoubleUtility((value) => only(blockSpacing: value)); - } - - @override - T only({ - MdTextStyleDto? headline1, - MdTextStyleDto? headline2, - MdTextStyleDto? headline3, - MdTextStyleDto? headline4, - MdTextStyleDto? headline5, - MdTextStyleDto? headline6, - MdTextStyleDto? paragraph, - TextStyleDto? link, - double? blockSpacing, - MdListDto? list, - MdTableDto? table, - MdCodeDto? code, - MdBlockQuoteDto? blockquote, - BoxSpecAttribute? innerContainer, - BoxSpecAttribute? outerContainer, - BoxSpecAttribute? contentContainer, - MdDividerDto? divider, - ImageSpecAttribute? image, - }) { - return builder( - SlideSpecAttribute( - headline1: headline1, - headline2: headline2, - headline3: headline3, - headline4: headline4, - headline5: headline5, - headline6: headline6, - paragraph: paragraph, - link: link, - blockSpacing: blockSpacing, - list: list, - table: table, - code: code, - blockquote: blockquote, - innerContainer: innerContainer, - outerContainer: outerContainer, - contentContainer: contentContainer, - divider: divider, - image: image, - ), - ); - } -} - -class MdTextStyleUtil - extends DtoUtility { - const MdTextStyleUtil(super.builder) : super(valueToDto: MdTextStyleDto.from); - - SpacingUtility get padding { - return SpacingUtility((value) => only(padding: value)); - } - - TextStyleUtility get textStyle { - return TextStyleUtility((value) => only(textStyle: value)); - } - - @override - T only({ - TextStyleDto? textStyle, - SpacingDto? padding, - }) { - return builder( - MdTextStyleDto( - textStyle: textStyle, - padding: padding, - ), - ); - } - - T call({ - TextStyle? textStyle, - EdgeInsets? padding, - }) { - return only( - textStyle: TextStyleDto.maybeAs(textStyle), - padding: SpacingDto.maybeFrom(padding), - ); - } -} - -class MdDividerUtil - extends DtoUtility { - const MdDividerUtil(super.builder) : super(valueToDto: MdDividerDto.from); - - DoubleUtility get height { - return DoubleUtility((value) => only(dividerHeight: value)); - } - - ColorUtility get color { - return ColorUtility((value) => only(dividerColor: value)); - } - - DoubleUtility get thickness { - return DoubleUtility((value) => only(dividerThickness: value)); - } - - @override - T only({ - double? dividerHeight, - ColorDto? dividerColor, - double? dividerThickness, - }) { - return builder( - MdDividerDto( - height: dividerHeight, - color: dividerColor, - thickness: dividerThickness, - ), - ); - } -} - -class MdListUtil - extends DtoUtility { - const MdListUtil(super.builder) : super(valueToDto: MdListDto.from); - - TextStyleUtility get textStyle { - return TextStyleUtility((value) => only(textStyle: value)); - } - - TextStyleUtility get item { - return TextStyleUtility((value) => only(item: value)); - } - - TextStyleUtility get itemMarker { - return TextStyleUtility((value) => only(itemMarker: value)); - } - - DoubleUtility get itemMarkerTrailingSpace { - return DoubleUtility((value) => only(itemMarkerTrailingSpace: value)); - } - - DoubleUtility get itemMinIndent { - return DoubleUtility((value) => only(itemMinIndent: value)); - } - - @override - T only({ - TextStyleDto? textStyle, - TextStyleDto? item, - TextStyleDto? itemMarker, - double? itemMinIndent, - double? itemMarkerTrailingSpace, - }) { - return builder( - MdListDto( - textStyle: textStyle, - item: item, - itemMarker: itemMarker, - itemMinIndent: itemMinIndent, - itemMarkerTrailingSpace: itemMarkerTrailingSpace, - ), - ); - } -} - -class TableBorderUtility - extends DtoUtility { - const TableBorderUtility(super.builder) - : super(valueToDto: TableBorderDto.from); - - BorderSideUtility get top { - return BorderSideUtility((value) => only(top: value)); - } - - BorderSideUtility get right { - return BorderSideUtility((value) => only(right: value)); - } - - BorderSideUtility get bottom { - return BorderSideUtility((value) => only(bottom: value)); - } - - BorderSideUtility get left { - return BorderSideUtility((value) => only(left: value)); - } - - BorderSideUtility get horizontalInside { - return BorderSideUtility((value) => only(horizontalInside: value)); - } - - BorderSideUtility get verticalInside { - return BorderSideUtility((value) => only(verticalInside: value)); - } - - BorderSideUtility get all { - return BorderSideUtility((value) => only( - top: value, - right: value, - bottom: value, - left: value, - horizontalInside: value, - verticalInside: value, - )); - } - - @override - T only({ - BorderSideDto? top, - BorderSideDto? right, - BorderSideDto? bottom, - BorderSideDto? left, - BorderSideDto? horizontalInside, - BorderSideDto? verticalInside, - BorderRadiusGeometryDto? borderRadius, - }) { - return builder( - TableBorderDto( - top: top, - right: right, - bottom: bottom, - left: left, - horizontalInside: horizontalInside, - verticalInside: verticalInside, - borderRadius: borderRadius, - ), - ); - } -} - -class MarkdownAlternatingUtility - extends ScalarUtility { - const MarkdownAlternatingUtility(super.builder); - - T odd() => builder(MarkdownAlternating.odd); - T even() => builder(MarkdownAlternating.even); -} - -class MdTableUtil - extends DtoUtility { - const MdTableUtil(super.builder) : super(valueToDto: MdTableDto.from); - - TextStyleUtility get textStyle { - return TextStyleUtility((value) => only(textStyle: value)); - } - - TextStyleUtility get head { - return TextStyleUtility((value) => only(head: value)); - } - - TextStyleUtility get body { - return TextStyleUtility((value) => only(body: value)); - } - - TableBorderUtility get border { - return TableBorderUtility((value) => only(border: value)); - } - - BoxDecorationUtility get rowDecoration { - return BoxDecorationUtility((value) => only(rowDecoration: value)); - } - - MarkdownAlternatingUtility get rowDecorationAlternating { - return MarkdownAlternatingUtility( - (value) => only(rowDecorationAlternating: value), - ); - } - - SpacingUtility get cellPadding { - return SpacingUtility((value) => only(cellPadding: value)); - } - - T tableColumnWidth(TableColumnWidth value) { - return only(columnWidth: value); - } - - @override - T only({ - TextStyleDto? textStyle, - TextStyleDto? head, - TextStyleDto? body, - TableBorderDto? border, - BoxDecorationDto? rowDecoration, - MarkdownAlternating? rowDecorationAlternating, - SpacingDto? cellPadding, - TableColumnWidth? columnWidth, - }) { - return builder( - MdTableDto( - textStyle: textStyle, - head: head, - body: body, - border: border, - rowDecoration: rowDecoration, - rowDecorationAlternating: rowDecorationAlternating, - cellPadding: cellPadding, - columnWidth: columnWidth, - ), - ); - } -} - -class MdCodeUtil - extends DtoUtility { - const MdCodeUtil(super.builder) : super(valueToDto: MdCodeDto.from); - - TextStyleUtility get span { - return TextStyleUtility((value) => only(span: value)); - } - - TextStyleUtility get textStyle { - return TextStyleUtility((value) => only(textStyle: value)); - } - - SpacingUtility get padding { - return SpacingUtility((value) => only(padding: value)); - } - - BoxDecorationUtility get decoration { - return BoxDecorationUtility((value) => only(decoration: value)); - } - // codeSpan - - ColorUtility get copyIconColor { - return ColorUtility((value) => only(copyIconColor: value)); - } - - @override - T only({ - TextStyleDto? span, - SpacingDto? padding, - BoxDecorationDto? decoration, - ColorDto? copyIconColor, - TextStyleDto? textStyle, - }) { - return builder( - MdCodeDto( - span: span, - padding: padding, - decoration: decoration, - copyIconColor: copyIconColor, - textStyle: textStyle, - ), - ); - } -} - -class MdBlockQuoteUtil - extends DtoUtility { - const MdBlockQuoteUtil(super.builder) - : super(valueToDto: MdBlockQuoteDto.from); - - TextStyleUtility get textStyle { - return TextStyleUtility((value) => only(textStyle: value)); - } - - BoxDecorationUtility get decoration { - return BoxDecorationUtility((value) => only(decoration: value)); - } - - SpacingUtility get padding { - return SpacingUtility((value) => only(padding: value)); - } - - SpacingUtility get contentPadding { - return SpacingUtility((value) => only(contentPadding: value)); - } - - @override - T only({ - TextStyleDto? textStyle, - BoxDecorationDto? decoration, - SpacingDto? padding, - SpacingDto? contentPadding, - }) { - return builder( - MdBlockQuoteDto( - textStyle: textStyle, - decoration: decoration, - padding: padding, - contentPadding: contentPadding, - ), - ); - } -} diff --git a/lib/superdeck.dart b/lib/superdeck.dart index 4f41c8e..dc013a9 100644 --- a/lib/superdeck.dart +++ b/lib/superdeck.dart @@ -6,9 +6,6 @@ export 'package:superdeck/models/asset_model.dart'; export 'package:superdeck/models/options_model.dart'; export 'package:superdeck/models/slide_model.dart'; export 'package:superdeck/providers/controller.dart'; -export 'package:superdeck/styles/style_attribute.dart'; -export 'package:superdeck/styles/style_dto.dart'; export 'package:superdeck/styles/style_spec.dart'; -export 'package:superdeck/styles/style_util.dart'; export 'components/organisms/app_shell.dart'; diff --git a/pubspec.lock b/pubspec.lock index dbe0af5..7bcaf62 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -125,10 +125,10 @@ packages: dependency: "direct dev" description: name: build_runner - sha256: "3ac61a79bfb6f6cc11f693591063a7f19a7af628dc52f141743edac5c16e8c22" + sha256: "1414d6d733a85d8ad2f1dfcb3ea7945759e35a123cb99ccfac75d0758f75edfa" url: "https://pub.dev" source: hosted - version: "2.4.9" + version: "2.4.10" build_runner_core: dependency: transitive description: @@ -293,26 +293,26 @@ packages: dependency: "direct dev" description: name: custom_lint - sha256: "22bd87a362f433ba6aae127a7bac2838645270737f3721b180916d7c5946cb5d" + sha256: "7c0aec12df22f9082146c354692056677f1e70bc43471644d1fdb36c6fdda799" url: "https://pub.dev" source: hosted - version: "0.5.11" + version: "0.6.4" custom_lint_builder: dependency: transitive description: name: custom_lint_builder - sha256: "0d48e002438950f9582e574ef806b2bea5719d8d14c0f9f754fbad729bcf3b19" + sha256: d7dc41e709dde223806660268678be7993559e523eb3164e2a1425fd6f7615a9 url: "https://pub.dev" source: hosted - version: "0.5.14" + version: "0.6.4" custom_lint_core: dependency: transitive description: name: custom_lint_core - sha256: "2952837953022de610dacb464f045594854ced6506ac7f76af28d4a6490e189b" + sha256: a85e8f78f4c52f6c63cdaf8c872eb573db0231dcdf3c3a5906d493c1f8bc20e6 url: "https://pub.dev" source: hosted - version: "0.5.14" + version: "0.6.3" dart_mappable: dependency: "direct main" description: @@ -402,10 +402,10 @@ packages: dependency: "direct dev" description: name: flutter_lints - sha256: "9e8c3858111da373efc5aa341de011d9bd23e2c5c5e0c62bccf32438e192d7b1" + sha256: "3f41d009ba7172d5ff9be5f6e6e6abb4300e263aab8866d2a0842ed2a70f8f0c" url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "4.0.0" flutter_plugin_android_lifecycle: dependency: transitive description: @@ -428,10 +428,10 @@ packages: dependency: transitive description: name: freezed_annotation - sha256: c3fd9336eb55a38cc1bbd79ab17573113a8deccd0ecbbf926cca3c62803b5c2d + sha256: f9f6597ac43cc262fa7d7f2e65259a6060c23a560525d1f2631be374540f2a9b url: "https://pub.dev" source: hosted - version: "2.4.1" + version: "2.4.3" frontend_server_client: dependency: transitive description: @@ -452,10 +452,10 @@ packages: dependency: "direct main" description: name: go_router - sha256: b465e99ce64ba75e61c8c0ce3d87b66d8ac07f0b35d0a7e0263fcfc10f99e836 + sha256: abec47eb8c8c36ebf41d0a4c64dbbe7f956e39a012b3aafc530e951bdc12fe3f url: "https://pub.dev" source: hosted - version: "13.2.5" + version: "14.1.4" graphs: dependency: transitive description: @@ -540,34 +540,34 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" url: "https://pub.dev" source: hosted - version: "10.0.0" + version: "10.0.4" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.3" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.1" lints: dependency: transitive description: name: lints - sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290 + sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235" url: "https://pub.dev" source: hosted - version: "3.0.0" + version: "4.0.0" localstorage: dependency: "direct main" description: @@ -612,10 +612,10 @@ packages: dependency: transitive description: name: meta - sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 + sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.12.0" mime: dependency: transitive description: @@ -627,11 +627,33 @@ packages: mix: dependency: "direct main" description: - name: mix - sha256: "68d46b5829beabd8589eec2388765230b33a9d7b8fd508758eb23fb9e09a1ce7" + path: "../mix/packages/mix" + relative: true + source: path + version: "1.2.0" + mix_annotations: + dependency: "direct main" + description: + name: mix_annotations + sha256: f77b013274e5c61508a28b7142928ca5593d40693418163812d05f5ac8cd06a4 url: "https://pub.dev" source: hosted - version: "1.0.0-beta.13" + version: "0.2.0" + mix_generator: + dependency: "direct dev" + description: + path: "../mix/packages/mix_generator" + relative: true + source: path + version: "0.2.0" + mix_lint: + dependency: "direct dev" + description: + name: mix_lint + sha256: "2f684dc18e46341a25f3e2dff46355d11746866bf70bdc99a0424809a3345883" + url: "https://pub.dev" + source: hosted + version: "0.1.0" node_preamble: dependency: transitive description: @@ -852,34 +874,26 @@ packages: dependency: "direct main" description: name: signals - sha256: "623a12333d53aeeaebeca83db2c7be04d09c46226d1bf9e3b5023fd1517399ed" + sha256: "38052d9107b4ae54b6b47a0e4625f31e6b4486decc8d92f113b3b557de6d4767" url: "https://pub.dev" source: hosted - version: "5.2.0" + version: "5.2.1" signals_core: dependency: transitive description: name: signals_core - sha256: e6d4940367e595c49fb93c1b918bfb03459d60ef7b7f9469befb5c236b6e20d0 + sha256: e34d9e3a5125f2063a6a3817729961cf948ca8cfdd66b6036c1c8c48735d2dda url: "https://pub.dev" source: hosted - version: "5.1.0" + version: "5.2.0" signals_flutter: dependency: transitive description: name: signals_flutter - sha256: "74e78aa2da49984c32576817fc878f16feb6f1e57278898835659cc85a023f9f" - url: "https://pub.dev" - source: hosted - version: "5.2.0" - signals_lint: - dependency: "direct dev" - description: - name: signals_lint - sha256: d55e1aa9a9b6d41234a53f9ed8b14f87d32b155711dccebb2e28d068fdee965d + sha256: d37006c8dc92e86aa80900d3d1eeb1ba62ae7bd67378d8cbea187c2730ad090d url: "https://pub.dev" source: hosted - version: "5.0.0" + version: "5.2.1" sky_engine: dependency: transitive description: flutter @@ -1001,26 +1015,26 @@ packages: dependency: transitive description: name: test - sha256: a1f7595805820fcc05e5c52e3a231aedd0b72972cb333e8c738a8b1239448b6f + sha256: "7ee446762c2c50b3bd4ea96fe13ffac69919352bd3b4b17bac3f3465edc58073" url: "https://pub.dev" source: hosted - version: "1.24.9" + version: "1.25.2" test_api: dependency: transitive description: name: test_api - sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" + sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" url: "https://pub.dev" source: hosted - version: "0.6.1" + version: "0.7.0" test_core: dependency: transitive description: name: test_core - sha256: a757b14fc47507060a162cc2530d9a4a2f92f5100a952c7443b5cad5ef5b106a + sha256: "2bc4b4ecddd75309300d8096f781c0e3280ca1ef85beda558d33fcbedc2eead4" url: "https://pub.dev" source: hosted - version: "0.5.9" + version: "0.6.0" timing: dependency: transitive description: @@ -1145,10 +1159,10 @@ packages: dependency: transitive description: name: vm_service - sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 + sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" url: "https://pub.dev" source: hosted - version: "13.0.0" + version: "14.2.1" watcher: dependency: "direct main" description: @@ -1193,10 +1207,10 @@ packages: dependency: "direct main" description: name: window_manager - sha256: b3c895bdf936c77b83c5254bec2e6b3f066710c1f89c38b20b8acc382b525494 + sha256: "8699323b30da4cdbe2aa2e7c9de567a6abd8a97d9a5c850a3c86dcd0b34bbfbf" url: "https://pub.dev" source: hosted - version: "0.3.8" + version: "0.3.9" xdg_directories: dependency: transitive description: @@ -1222,5 +1236,5 @@ packages: source: hosted version: "3.1.2" sdks: - dart: ">=3.3.0 <4.0.0" + dart: ">=3.4.0 <4.0.0" flutter: ">=3.19.0" diff --git a/pubspec.yaml b/pubspec.yaml index ee824ca..8c56cc6 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -9,9 +9,8 @@ environment: dependencies: flutter: sdk: flutter - mix: ^1.0.0-beta.13 cached_network_image: ^3.3.1 - window_manager: ^0.3.8 + window_manager: ^0.3.9 watcher: ^1.1.0 collection: ^1.18.0 path: ^1.9.0 @@ -22,26 +21,30 @@ dependencies: animate_do: ^3.3.4 recase: ^4.1.0 syntax_highlight: ^0.4.0 - signals: ^5.2.0 + signals: ^5.2.1 scrollable_positioned_list: ^0.3.8 pdf: ^3.10.8 localstorage: ^5.0.0 - go_router: ^13.2.5 + go_router: ^14.1.4 file_picker: ^8.0.3 universal_html: ^2.2.4 path_provider: ^2.1.3 url_launcher: ^6.2.6 + mix: ^1.2.0 + mix_annotations: ^0.2.0 dev_dependencies: flutter_test: sdk: flutter - flutter_lints: ^3.0.2 - custom_lint: ^0.5.11 - build_runner: ^2.4.9 - signals_lint: ^5.0.0 + flutter_lints: ^4.0.0 + build_runner: ^2.4.10 dart_mappable_builder: ^4.2.3 build_verify: ^3.1.0 + mix_generator: ^0.2.0 + custom_lint: ^0.6.4 + mix_lint: ^0.1.0 + flutter: assets: diff --git a/pubspec_overrides.yaml b/pubspec_overrides.yaml new file mode 100644 index 0000000..4556263 --- /dev/null +++ b/pubspec_overrides.yaml @@ -0,0 +1,5 @@ +dependency_overrides: + mix_generator: + path: ../mix/packages/mix_generator + mix: + path: ../mix/packages/mix \ No newline at end of file