Skip to content

Inconsistent TextDecoration API across platforms #181662

Description

@Pante

Steps to reproduce

The following code snippet compiles fine.

final class _TextDecorationSentinel implements TextDecoration {
  const _TextDecorationSentinel();

  @override
  bool contains(TextDecoration other) => throw UnimplementedError();
}

However, when included in flutter build web, it fails with the following error:

Error: The non-abstract class '_TextDecorationSentinel' is missing implementations for these members:
 - TextDecoration.maskValue
final class _TextDecorationSentinel implements TextDecoration {
            ^^^^^^^^^^^^^^^^^^^^^^^
org-dartlang-sdk:///lib/ui/text.dart@7688+9:
Info: 'TextDecoration.maskValue' is defined here.
Error: Compilation failed.
  Command: /opt/hostedtoolcache/flutter/stable-3.38.8-x64/bin/cache/dart-sdk/bin/dart compile js --platform-binaries=/opt/hostedtoolcache/flutter/stable-3.38.8-x64/bin/cache/flutter_web_sdk/kernel --invoker=flutter_tool -Ddart.vm.product=true -DFLUTTER_VERSION=3.38.8 -DFLUTTER_CHANNEL=stable -DFLUTTER_GIT_URL=https://github.com/flutter/flutter.git -DFLUTTER_FRAMEWORK_REVISION=bd7a4a6b55 -DFLUTTER_ENGINE_REVISION=db373eb85a -DFLUTTER_DART_VERSION=3.10.7 -DFLUTTER_WEB_USE_SKIA=true -DFLUTTER_WEB_USE_SKWASM=false -DFLUTTER_WEB_CANVASKIT_URL=https://www.gstatic.com/flutter-canvaskit/db373eb85a06eb3d706af362a45d42d0972f4b46/ --native-null-assertions --no-source-maps -O4 --minify -o /home/runner/work/forui/forui/docs_snippets/.dart_tool/flutter_build/501bed0340027eb75ea43b3c1b94a2ec/app.dill --packages=/home/runner/work/forui/forui/.dart_tool/package_config.json --cfe-only /home/runner/work/forui/forui/docs_snippets/.dart_tool/flutter_build/501bed0340027eb75ea43b3c1b94a2ec/main.dart

Looking at the source code, TextDecoration's implementation is different across platforms.

On web, it is

int get maskValue => _mask;
.

On non-web platforms, the implementation is missing the maskValue getter:

/// A linear decoration to draw near the text.
class TextDecoration {
  const TextDecoration._(this._mask);

  /// Creates a decoration that paints the union of all the given decorations.
  factory TextDecoration.combine(List<TextDecoration> decorations) {
    int mask = 0;
    for (final TextDecoration decoration in decorations) {
      mask |= decoration._mask;
    }
    return TextDecoration._(mask);
  }

  final int _mask;

  /// Whether this decoration will paint at least as much decoration as the given decoration.
  bool contains(TextDecoration other) {
    return (_mask | other._mask) == _mask;
  }

  /// Do not draw a decoration
  static const TextDecoration none = TextDecoration._(0x0);

  /// Draw a line underneath each line of text
  static const TextDecoration underline = TextDecoration._(0x1);

  /// Draw a line above each line of text
  static const TextDecoration overline = TextDecoration._(0x2);

  /// Draw a line through each line of text
  static const TextDecoration lineThrough = TextDecoration._(0x4);

  @override
  bool operator ==(Object other) {
    return other is TextDecoration && other._mask == _mask;
  }

  @override
  int get hashCode => _mask.hashCode;

  @override
  String toString() {
    if (_mask == 0) {
      return 'TextDecoration.none';
    }
    final List<String> values = <String>[];
    if (_mask & underline._mask != 0) {
      values.add('underline');
    }
    if (_mask & overline._mask != 0) {
      values.add('overline');
    }
    if (_mask & lineThrough._mask != 0) {
      values.add('lineThrough');
    }
    if (values.length == 1) {
      return 'TextDecoration.${values[0]}';
    }
    return 'TextDecoration.combine([${values.join(", ")}])';
  }
}

https://api.flutter.dev/flutter/dart-ui/TextDecoration-class.html

Expected results

NIL

Actual results

NIL

Code sample

NIL

Screenshots or Video

Logs

No response

Flutter Doctor output

Doctor output
flutter doctor --verbose
[✓] Flutter (Channel stable, 3.38.8, on macOS 15.7.3 24G419 darwin-arm64, locale en-SG) [460ms]
    • Flutter version 3.38.8 on channel stable at /Users/matthias/Documents/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision bd7a4a6b55 (3 days ago), 2026-01-26 15:21:03 -0800
    • Engine revision db373eb85a
    • Dart version 3.10.7
    • DevTools version 2.51.1
    • Feature flags: enable-web, enable-linux-desktop, enable-macos-desktop, enable-windows-desktop, enable-android, enable-ios, cli-animations, enable-native-assets, omit-legacy-version-file, enable-lldb-debugging, enable-uiscene-migration

[✓] Android toolchain - develop for Android devices (Android SDK version 36.0.0) [1,720ms]
    • Android SDK at /Users/matthias/Library/Android/sdk
    • Emulator version 36.1.9.0 (build_id 13823996) (CL:N/A)
    • Platform android-36, build-tools 36.0.0
    • Java binary at: /Users/matthias/Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
      This is the JDK bundled with the latest Android Studio installation on this machine.
      To manually set the JDK path, use: `flutter config --jdk-dir="path/to/jdk"`.
    • Java version OpenJDK Runtime Environment (build 21.0.8+-14196175-b1038.72)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 26.2) [1,095ms]
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 17C52
    • CocoaPods version 1.16.2

[✓] Chrome - develop for the web [6ms]
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Connected device (2 available) [6.4s]
    • macOS (desktop) • macos  • darwin-arm64   • macOS 15.7.3 24G419 darwin-arm64
    • Chrome (web)    • chrome • web-javascript • Google Chrome 144.0.7559.97
    ! Error: Browsing on the local area network for Overpriced Phone. Ensure the device is unlocked and attached with a cable or associated with the same local area network as this Mac.
      The device must be opted into Developer Mode to connect wirelessly. (code -27)

[✓] Network resources [292ms]
    • All expected network resources are available.

• No issues found!

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work lista: buildBuilding flutter applications with the toola: error messageError messages from the Flutter frameworka: releaseChallenges faced when attempting to productionize an appa: typographyText rendering, possibly libtxtc: crashStack traces logged to the consoleengineflutter/engine related. See also e: labels.f: material designflutter/packages/flutter/material repository.found in release: 3.38Found to occur in 3.38found in release: 3.41Found to occur in 3.41frameworkflutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onplatform-webWeb applications specificallyr: fixedIssue is closed as already fixed in a newer versionteam-webOwned by Web platform teamtoolAffects the "flutter" command-line tool. See also t: labels.triaged-webTriaged by Web platform team

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions