flutter_html_css_interaction
A flutter_html extension that renders the CSS
pointer-events, user-select and cursor properties. flutter_html 3.0.0 parses
none of the three. It drops them from an inline style, and there is no error and no
warning. user-select needs a SelectionArea above the Html widget, and cursor
needs a pointing device.
Contents
Features
pointer-events: nonewraps the element in anIgnorePointer.user-select: nonewraps it in aSelectionContainer.disabled.cursor: <keyword>wraps it in aMouseRegion. 35 keywords are mapped, the eight directional resize cursors included.- A comma-separated
cursorlist resolves to its first keyword that maps; the extension skipsurl()andimage-set()entries. - A
-webkit-,-moz-,-ms-or-o-prefix resolves on property names andcursorkeywords. extraCursorsadds a keyword to the map, or replaces one already in it.- An element whose final inline style holds none of the three properties gets no wrapper.
Getting started
dependencies:
flutter_html: ^3.0.0
flutter_html_css_interaction: ^0.2.0
Usage
import 'package:flutter_html/flutter_html.dart';
import 'package:flutter_html_css_interaction/flutter_html_css_interaction.dart';
Html(
data: '''
<div style="cursor: pointer; user-select: none;">Click me, do not select me</div>
<div style="pointer-events: none;">Not a hit target</div>
''',
extensions: const [CssInteractionHtmlExtension()],
);
Before you register it
This extension matches on the inline style, never on the tag name. It cannot make
flutter_html render a tag that has no renderer. A TagExtension does that.
List this extension before every TagExtension. flutter_html builds an element with
the first extension in the list that matches it. A TagExtension matches on the tag
name and builds the element outright. List the TagExtension first and this extension
never runs. The element still renders without its wrapper, and there is no error and no
warning.
Html(
data: '<v-card style="cursor: pointer;">Card</v-card>',
extensions: [
const CssInteractionHtmlExtension(), // must come first
TagExtension(tagsToExtend: const {'v-card'}, child: const Text('Card')),
],
);
Against another extension that wraps at the building step, whichever is listed first is
the outer wrapper. flutter_html_css_size_constraints 0.1.1 guards its own
node the way this 0.1.1 does, so either order builds one ConstrainedBox and one
MouseRegion. Against the released 0.1.0, which has no guard, list this extension
first: in the other order it runs twice and wraps twice, one wasted widget for a fixed
size and a wrong result for a percentage one.
Order against a utility-class extension does not matter. This extension reads the inline
style at the building step, after a utility-class extension expands every class.
Released flutter_html_bootstrap 0.1.1 and
flutter_html_vuetify 0.1.0 do not recognise CssInteractionHtmlExtension.
Both therefore still suppress the classes this extension could render. Write
pointer-events, user-select and cursor into an inline style attribute until a
release of theirs lists it.
Limitations
cursorneeds a pointing device. On a touch-only platform it changes nothing.user-selectneeds aSelectionAreaor aSelectableRegionabove theHtmlwidget.- A styled inline run, such as a
<span>, becomes a widget. It no longer breaks across lines with the text around it, and there is no error and no warning. Put the declaration on a block element instead. pointer-events: none !importantanduser-select: none !importantrender nothing, and there is no error and no warning.cursor: pointer !importantresolves. Remove the!important.pointer-events: noneon the same element also suppresses thecursor, as CSS does.pointer-events: autoand the SVG-only keywords render nothing.IgnorePointerblocks the whole subtree.user-select: text,auto,allandcontainrender nothing. Onlynonehas a Flutter counterpart.cursor: autoand the CSS-wide keywords render nothing. Writecursor: defaultfor the arrow pointer.cursor: url()andcursor: image-set()render nothing. Flutter has no API for a custom cursor image.- An unmapped
cursorkeyword renders nothing. There is no error and no warning. - The extension reads the inline style only. It does not read
<style>blocks or stylesheets.
The keyword table and the reasoning behind each one are on the symbols that implement them.
Additional information
Issues and merge requests go to the
GitLab repository.
Rounding the same element's corners is
flutter_html_css_border_radius's
job.
CI, publishing and Renovate are described in CONTRIBUTING.md.