Dropsource / monarch

Monarch is a tool for building Flutter widgets in isolation. It makes it easy to build, test and debug complex UIs.
https://monarchapp.io
MIT License
438 stars 23 forks source link

Assets not found for package project #122

Open natt-han opened 1 year ago

natt-han commented 1 year ago

I'm not sure is Monarch support set up inside package project? I found a problem that monarch can't find assets.

In my widget I load assets with my package name SvgPicture.asset( 'assets/images/header_bg.svg', package: 'my_package', ),

I found a work around to make It work by copy files from '.monarch/flutter_assets/assets/images' to '.monarch/flutter_assets/packages/my_package/assets/images'

fertrig commented 1 year ago

It should work.

Here is a story which loads an image asset using the package name: https://github.com/Dropsource/scratch_image/blob/main/scratch_image/stories/images_stories.dart

natt-han commented 1 year ago

that different from my setup. here a example repo https://github.com/natt-han/monarch_test

this is widget https://github.com/natt-han/monarch_test/blob/main/lib/asset_widget.dart this is story https://github.com/natt-han/monarch_test/blob/main/stories/asset_widget_stories.dart

mijiga commented 12 months ago

that different from my setup. here a example repo https://github.com/natt-han/monarch_test

this is widget https://github.com/natt-han/monarch_test/blob/main/lib/asset_widget.dart this is story https://github.com/natt-han/monarch_test/blob/main/stories/asset_widget_stories.dart

It only makes sense to use the package argument when you want to reference assets in a package outside of the one from which you are calling Image.asset. In your case both the asset and the Image.asset call are in the same package which Is unnecessary and is the possible cause for failure.

Try creating and referring to a different package name and make sure you call monarch init after you create the new package. Also make sure you have correctly added the package to your pubspec.yaml

natt-han commented 12 months ago

but this is how I want It to be. the example repo is a package type project. there will be another application type project as the main project that will use AssetWidget from this package, so the package argument is required.

I want to set up monarch in a package project so that I can build and test it quickly from the package project it self, but I found this problem.

mijiga commented 12 months ago

Unless I'm mistaken but based on that, you should use Image.asset() as below:

Let's call the package containing AssetWidget 'asset_widget_package'

natt-han commented 12 months ago

Unless I'm mistaken but based on that, you should use Image.asset() as below:

Let's call the package containing AssetWidget 'asset_widget_package'

  • When refering to assets in the main_project from within the main project : Image.asset('flutter.png')
  • Refering to assets in asset_wiget_package from the main_project: Image.asset('flutter.png', package: 'asset_widget_package' )
  • Referring to assets in asset_wdiget_package from within asset_wdiget_package: Image.asset('flutter.png')

In main_project I will not directly referring to assets in asset_wiget_package, but will use widgets from asset_wiget_package in those widget will use asset from asset_wiget_package it self.

It same as Icons packages like this one that have to use package argument.

fertrig commented 11 months ago

@natt-han, you are correct on how you want to use the Image.asset('foo.png', package: 'my_package') from inside your package project. However, at runtime, Flutter wants my_package to exist as a package dependency.

If you add a main.dart to my_package project and run it, Flutter will fail with message "Unable to load asset" when it calls Image.asset('foo.png', package: 'my_package'). Thus, at runtime, calls to Image.asset('foo.png', package: 'my_package') will only work in the context of another project, not from my_package.

To use your assets within Monarch here are 3 options:

  1. Automate the workaround you described above. That one is interesting and something I'd like to know more. Please let us know how that works.

  2. Create another package just for your stories, let's call it my_package_stories. Then, my_package will be a dependency of my_package_stories. my_package_stories will have the stories for your package. You would call monarch from inside your my_package_stories.

  3. Expose package as a property you can override so you can pass null from your stories.

    
    /// asset_widget.dart
    class AssetWidget extends StatelessWidget {
    final String? package;
    AssetWidget({super.key, this.package = 'monarch_test'});
    
    @override
    Widget build(BuildContext context) {
    return Image.asset('assets/flutter.png', package: package);
    }
    }

/// asset_widget_stories.dart Widget assetWidget() => AssetWidget(package: null);

/// from another project you won't need to pass package, you could just call: AssetWidget()



I hope this helps.