lucide-icons / lucide-flutter

Archived package of Lucide Flutter
4 stars 3 forks source link

New lucide flutter api & improve flutter package #2

Open ericfennis opened 1 year ago

ericfennis commented 1 year ago

The flutter plugin is not matching the standards of the other packages of lucide.

It would be nice if the flutter plugin uses widgets (flutter components) to render icons instead of the icon font. We could use https://pub.dev/packages/flutter_svg for this. During build time we can generate all the widget files for the icons and create the export.

The icon widgets should have the following options, so it matches the other apis of lucide

  1. color
  2. size
  3. stroke width

Unfortunately I'm not really into Dart so if someone can take this challenge/issue, that would be nice. I can help with rendering the Widget files from the icons if you need help with that.

It would be nice if the existing implementation will still work if someone install the new version so notting will break.

This probably will fix lucide-icons/lucide#407 and lucide-icons/lucide#801

Odas0R commented 1 year ago

Any news on this?

Odas0R commented 1 year ago

For a temporary fix: (Using the flutter_svg.dart package)

#!/usr/bin/env bash

gitRoot=$(git rev-parse --show-toplevel)

# Destination directory for icons
DIR="${gitRoot}/assets/icons"
OUT="${gitRoot}/lib/app_icons.dart"

# Process each .svg file
for file in "${DIR}"/*.svg; do
  base=$(basename "$file" .svg)

  widgetName=$(echo "$base" | awk -F"-" '{printf "%s", $1; for(i=2;i<=NF;i++){printf "%s%s", toupper(substr($i,1,1)), substr($i,2)}}')

  widgets+="  static final Widget ${widgetName} = SvgPicture.asset('assets/icons/lucid/${base}.svg');\n"
done

echo -e "import 'package:flutter_svg/flutter_svg.dart';\nimport 'package:flutter/material.dart';\n\nclass AppIcons {\n${widgets}\n}" >"$OUT"

Just download the icons and place them on $DIR and generate the AppIcons class with all the static properties of all icons

Note

I can submit a pr, but not atm. If someone can tell me how the icons are handled here, I'll give it a shot

ericfennis commented 1 year ago

@Odas0R No news on this. TBH I was already thinking of ditching this package because no one from the community is working on it 😅 But if you like to revive this, go ahead!

We really want to have a similar API as the other packages.

I'm not a dart or flutter expert, but I'll try to give a code example of what we have in mind. So if defining a new widget, it should be working something like this:

class Example extends StatelessWidget {
  const Example({super.key});

  @override
  Widget build(BuildContext context) {
    return HomeIcon(
       color: '#000',
       strokeWidth: 4,
       absoluteStrokeWidth: true,
       fill: '#ff0',
       //...etc
    );
  }
}

Let me know if you need any more explanation.

Odas0R commented 1 year ago

@Odas0R No news on this. TBH I was already thinking of ditching this package because no one from the community is working on it sweat_smile But if you like to revive this, go ahead!

We really want to have a similar API as the other packages.

I'm not a dart or flutter expert, but I'll try to give a code example of what we have in mind. So if defining a new widget, it should be working something like this:

class Example extends StatelessWidget {
  const Example({super.key});

  @override
  Widget build(BuildContext context) {
    return HomeIcon(
       color: '#000',
       strokeWidth: 4,
       absoluteStrokeWidth: true,
       fill: '#ff0',
       //...etc
    );
  }
}

Let me know if you need any more explanation.

Hey!

Yeah, that API is not possible, at least with the flutter_svg package. You can't set the strokeWidth, and some other properties, at least I couldn't find any info on that?

Odas0R commented 1 year ago

Alright, I'll give it a shot. :)

Would it be ok if I generate something like this?

class AppIcons {
  static SvgPicture accessibility({double width = 24.0, double height = 24.0}) => SvgPicture.asset('assets/icons/accessibility.svg', width: width, height: height);
  static SvgPicture activitySquare({double width = 24.0, double height = 24.0}) => SvgPicture.asset('assets/icons/activity-square.svg', width: width, height: height);
  static SvgPicture activity({double width = 24.0, double height = 24.0}) => SvgPicture.asset('assets/icons/activity.svg', width: width, height: height);
  static SvgPicture airplay({double width = 24.0, double height = 24.0}) => SvgPicture.asset('assets/icons/airplay.svg', width: width, height: height);
  static SvgPicture airVent({double width = 24.0, double height = 24.0}) => SvgPicture.asset('assets/icons/air-vent.svg', width: width, height: height);
  static SvgPicture alarmCheck({double width = 24.0, double height = 24.0}) => SvgPicture.asset('assets/icons/alarm-check.svg', width: width, height: height);
  static SvgPicture alarmClockOff({double width = 24.0, double height = 24.0}) => SvgPicture.asset('assets/icons/alarm-clock-off.svg', width: width, height: height);
  static SvgPicture alarmClock({double width = 24.0, double height = 24.0}) => SvgPicture.asset('assets/icons/alarm-clock.svg', width: width, height: height);
  static SvgPicture alarmMinus({double width = 24.0, double height = 24.0}) => SvgPicture.asset('assets/icons/alarm-minus.svg', width: width, height: height);
  static SvgPicture alarmPlus({double width = 24.0, double height = 24.0}) => SvgPicture.asset('assets/icons/alarm-plus.svg', width: width, height: height);
  ...
}

The idea is to do to exactly how you're doing it but use an external dependency to handle the svg's. This way you can create a function that wraps the dependency (which lets you set the strokeWidth, etc).

Here's how you would use it:

Button.secondary(
  prefix: AppIcons.mail(width: 24.0, strokeWidth: 3.0), // pass more props like height, etc
  align: ButtonAlign.grow,
  text: "Create account with Email",
  onPressed: () {
    context.go("/sign-up");
  },
),

Instead of AppIcons, would be LucidIcons, like you have.

Note

This is exactly how I'm currently using the icons from your repo. Many thanks for your work :). I'll gladly contribute!

I think I can manage this pretty quickly, just need to know what "approach" I should have here.

Update 12/07/2023

I found a way to alter the stroke-width using the flutter_svg package! I'm pretty good to go, just need to know if the API I have above is acceptable

ericfennis commented 1 year ago

@Odas0R Sorry for the late reply, I totally missed your comment. Glad you found a way of implementing the API, this looks promising! Yeah look totally fine to generate that first code snippet. For all other packages we generate icons as well.

Do you know if Flutter/Dart will "tree-shake" the icons you don't use?

Odas0R commented 1 year ago

@Odas0R Sorry for the late reply, I totally missed your comment. Glad you found a way of implementing the API, this looks promising! Yeah look totally fine to generate that first code snippet. For all other packages we generate icons as well.

Do you know if Flutter/Dart will "tree-shake" the icons you don't use?

No worries!

It can be tweaked yes. You can build an app using the release mode, eliminating dead code. It could be smart enough to understand which class properties are being used, removing the rest.

Not sure. I'm still pretty new to Flutter/Dart too :)

The code snippet above uses the icon's path, which is not ideal, it will clutter the bundle size. The solution should be getting the SVG element from the files and generating functions that return the svg as a string.

Same API mentioned above.

I'll send a pr soon then!

ericfennis commented 1 year ago

@Odas0R Awesome that would be great!

HrBDev commented 1 year ago

Have you explored the possibility of utilizing variable fonts by any chance?