Sub6Resources / flutter_html

A Flutter widget for rendering static html as Flutter widgets (Will render over 80 different html tags!)
https://pub.dev/packages/flutter_html
MIT License
1.8k stars 874 forks source link

[FEATURE]: Before and After selectors should accept widgets #1224

Open ZsoltFischer opened 1 year ago

ZsoltFischer commented 1 year ago

Before and after selectors should accept widgets

Currently the before selector can only be a String but some applications may require simple widgets, like icons. I propose the before parameter in style.dart to be replaced by a Widget or the class to be extended with an additional beforeWidget parameter.


Implementation example, going with the second suggestion (adding the extra beforeWidget parameter)

In replaced_element.dart create a WidgetContentElement class:

class WidgetContentElement extends ReplacedElement {
  Widget? widget;
  dom.Node? node;

  WidgetContentElement({
    required this.widget,
    this.node,
    required Style style,
    dom.Element? element,
  }) : super(
          name: '[widget]',
          style: style,
          node: element,
          elementId: '[[No ID]]',
          alignment: PlaceholderAlignment.top,
        );

  @override
  Widget? toWidget(_) => widget;
}

And in html_parser.dart/650 extend the _processBeforesAndAfters method like:

static StyledElement _processBeforesAndAfters(StyledElement tree) {

    if (tree.style.before != null) {

      tree.children.insert(
        0,
        TextContentElement(
          text: tree.style.before,
          style: tree.style
              .copyWith(beforeAfterNull: true, display: Display.inline),
        ),
      );

    }

    if (tree.style.beforeWidget != null) {
      tree.children.insert(
          0,
          WidgetContentElement(
              widget: tree.style.beforeWidget,
              style: tree.style.copyWith(
                  beforeAfterNull: true,
                  display: Display.inline,
                  alignment: Alignment.topCenter)));

    }

    if (tree.style.after != null) {
      tree.children.add(TextContentElement(
        text: tree.style.after,
        style:
            tree.style.copyWith(beforeAfterNull: true, display: Display.inline),
      ));
    }

    tree.children.forEach(_processBeforesAndAfters);

    return tree;

}

If you consider my suggestion but you deem my implementation poor, please reach out to me! I'm willing to dive deeper and help in a proper refactor. This workaround was just a quick solution for my project with a tight deadline :)

The same goes for the after selector as well of course!

Sub6Resources commented 1 year ago

I think there are some use cases where this is valid. It's not vanilla css like we prefer, so it won't be enabled by default, but I'll see if there are some good options for an extension mechanism that makes this possible.