Skip to content

Scrollbars on tables are drawn ~1 row too high #30

@TDuffinNTU

Description

@TDuffinNTU

Left: FixedWidth (100)
Right: IntrinsicWidth()

Image Image

I'm not too sure how this works but I'd happily recreate a minimal example for you! The markdown for this region is as follows:

# Tables

Colons can be used to align columns.

| Tables        | Are           | Cool  |
| ------------- |:-------------:| -----:|
| col 3 is      | right-aligned | $1600 |
| col 2 is      | centered      |   $12 |
| zebra stripes | are neat      |    $1 |

Here's a long table for you to enjoy...

| Tables        | Are           | Cool  | And           | Really  | Long  |
| ------------- |:-------------:| -----:|:-------------:| -------:| -----:|
| col 3 is      | right-aligned | $1600 | right-aligned | $Wahoo  | $Blop |
| col 2 is      | centered      |   $12 | centered      |   $12   |   $12 |
| zebra stripes | are neat      |    $1 | are neat      |    $1   |    $1 |
| zebra stripes | are neat      |    $1 | are neat      |    $1   |    $1 |

The code we're using to render this widget is a plain ole' MarkdownBody

class MarkdownRenderer extends StatelessWidget {
  const MarkdownRenderer({
    super.key,
    required this.data,
    required this.onLinkTap,
    this.textAlign = WrapAlignment.start,
  });

  /// The markdown document to display.
  final String data;

  /// Triggered when a URL is tapped.
  final Function(Uri linkUrl, String linkLabel) onLinkTap;

  final WrapAlignment textAlign;

  @override
  Widget build(BuildContext context) {
    final theme = CustomTheme.of(context);
    return MarkdownBody(
      data: data,
      fitContent: false,
      onTapLink: (text, url, title) {
        // TODO Can we get footnotes working..?
        if (url.isNullOrEmpty || url!.startsWith('#')) return;
        onLinkTap(Uri.parse(url), text);
      },
      //builders: {'th': TableHeadBuilder()},
      imageBuilder: (uri, title, alt) {
        // Ugly hack to support .svg files
        if (uri.path.toLowerCase().endsWith('.svg')) {
          return SvgPicture.network(
            uri.toString(),
            semanticsLabel: alt,
          );
        }
        return Image.network(
          uri.toString(),
          semanticLabel: alt,
        );
      },
      styleSheet: MarkdownStyleSheet(
        textAlign: textAlign,
        h1Align: textAlign,
        h2Align: textAlign,
        h3Align: textAlign,
        h4Align: textAlign,
        h5Align: textAlign,
        h6Align: textAlign,
        orderedListAlign: textAlign,
        unorderedListAlign: textAlign,
        blockquoteAlign: textAlign,
        tableColumnWidth: const IntrinsicColumnWidth(),
        tableScrollbarThumbVisibility: true,
        h1: theme.textTheme.headlineLarge,
        h2: theme.textTheme.headlineMedium,
        h3: theme.textTheme.headlineSmall,
        h4: theme.textTheme.titleLarge,
        h5: theme.textTheme.titleMedium,
        h6: theme.textTheme.titleSmall,
        p: theme.textTheme.bodyLarge,
        em: theme.textTheme.bodyLarge.copyWith(fontStyle: FontStyle.italic),
        strong: theme.textTheme.bodyLarge.copyWith(fontWeight: FontWeight.bold),
        a: theme.textTheme.link,
        blockquotePadding: const EdgeInsets.all(Spacing.l) + const EdgeInsets.only(left: Spacing.s),
        blockquoteDecoration: BoxDecoration(
          color: theme.palette.surfaceLowElevation,
          border: Border(
            left: BorderSide(color: theme.palette.primary, width: Spacing.s),
          ),
        ),
      ),
    );
  }
}

Which itself is wrapped in a Padding widget and SliverToBoxAdapter to fit inside a CustomScrollView beneath some other slivers. Editing the padding doesn't change the scrollbar position, nor does alignment or other theme elements here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions