Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SuperEditor] Fix list item vertical alignment (Resolves #1834) #1920

Merged

Conversation

angelosilvestre
Copy link
Collaborator

[SuperEditor] Fix list item vertical alignment. Resolves #1834

The dot in unordered list items is a bit misaligned when using a line height multiplier greater than 1.0. Here's one example with a 3.0 multiplier:

SCR-20240402-slvd

The misalignment is worse when using different font sizes (this also affects ordered list items)

SCR-20240402-smfh

This PR changes the list component to place the dot inside a WidgetSpan to properly align it. Also, the list components were changed use the attributions of the first character. This change was made because the list item might contain a FontSizeAttribution, which will affect the line height.

This was the result:

SCR-20240402-smzu

The alignment change caused some golden tests to fail, because now the dot is slightly above from where it was before.

We are still rendering differently from Google Docs. It scales the dot and doesn't seem to indent based on the font size:

SCR-20240402-spbt

Avoiding scaling the dot was intentional, due to previous conversations. We could change that if needed.

@matthew-carroll
Copy link
Contributor

@angelosilvestre is there a reason why we'd want different indentation based on font size? That sounds like a bug to me.

shape: BoxShape.circle,
color: component.styleBuilder({}).color,
child: Text.rich(
// Place a zero-width joiner before the bullet point to make it properly aligned. Without this,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you point out what specifically happens if we don't include this zero-width character? Also, should we move this comment immediately above the text: line? Because right now this comment appears to apply to the whole span, which includes the dot.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without the zero-width character the dot appears misaligned for small font sizes:

Without the zero-width character:

SCR-20240409-quir

With the zero-width character:

SCR-20240409-qumu

@angelosilvestre
Copy link
Collaborator Author

@angelosilvestre is there a reason why we'd want different indentation based on font size? That sounds like a bug to me.

@matthew-carroll This seems to be done on purpose. This is the method that computes then indentation:

double _defaultIndentCalculator(TextStyle textStyle, int indent) {
  return (textStyle.fontSize! * 0.60) * 4 * (indent   1);
}

@matthew-carroll
Copy link
Contributor

@angelosilvestre it seems likely that that behavior was designed while thinking about a list where all list items are the same size. If all list items have really big text, then it indents more, if all list items have tiny text, it indents less.

I doubt this work grappled with varying text sizes. It's obvious from your screenshots that the result of displaying list items at varying text sizes looks horrible and is unexpected. So we need to fix that.

Seems like we can either make it constant, or we'll need to search up and down the list to figure out the largest font size and base all list item indentations on that font size.

@angelosilvestre
Copy link
Collaborator Author

@matthew-carroll Based on the google docs example that I posted before I would say that we should be fine using a constant indentation.

SCR-20240402-spbt

@matthew-carroll
Copy link
Contributor

Ok, then let's do that.

@angelosilvestre
Copy link
Collaborator Author

@matthew-carroll For ordered lists I'm not sure how we should compute the indentation. Here's an example from Google Docs:

SCR-20240410-szwm

We can see that the numeral is left-aligned, but the distance between the numeral and the content isn't fixed.

@matthew-carroll
Copy link
Contributor

Hm. That's pretty weird. Can you post a few screenshots from a few other apps so we can compare?

@angelosilvestre
Copy link
Collaborator Author

Apple Notes

SCR-20240411-rmpg

The numerals look right-aligned, but it's also weird with bigger font sizes. Also, with two digits numerals it looks even more weird:

SCR-20240411-rnhm

Microsoft Word online

SCR-20240411-rpxm

Numerals are left-aligned and the indentation increases on bigger font sizes

Evernote

SCR-20240411-rrka

Doesn't scale the numeral.

Canva Docs

SCR-20240411-rxec

Numerals are left-aligned and the indentation increases on bigger font sizes

Other apps

Notion, Obsidian and ClickUp don't look like they support setting font sizes.

@matthew-carroll
Copy link
Contributor

Looking at those examples, I think right aligning the numerals looks best. The problem with the Apple version is that they allow different widths for the numerals. What if we make all the numerals in the same list take up the same width?

To accomplish that, we could have each list item take its font, font size, font style, and then immediately measure every numeral in the font: 0-9. That list item takes the widest value and multiplies it by the number of numerals used by that list item. Then all list items respect the widest value. We can cache the measurement so that the same font, at the same size, with the same style never needs to re-measure. That would work fine most lists.

What do you think?

@angelosilvestre
Copy link
Collaborator Author

@matthew-carroll Can we a separate PR's to avoid the fix for the vertical alignment with the horizontal alignment change?

Or do you prefer to keep all on the same PR?

@matthew-carroll
Copy link
Contributor

@angelosilvestre we can do them separately. Please file the appropriate issue and let me know when you think this PR has what it should.

@angelosilvestre
Copy link
Collaborator Author

@matthew-carroll I filed #1950

Could you please re-review this PR?

Copy link
Contributor

@matthew-carroll matthew-carroll left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

color: component.styleBuilder({}).color,
child: Text.rich(
TextSpan(
// Place a zero-width joiner before the bullet point to make it properly aligned. Without this,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I won't hold up on the PR on this, but can you file an issue with Flutter including repro steps to show mis-alignment in the absence of the spacer? No need to include attributed text in that - just use direct Flutter stuff that demonstrates both options.

@matthew-carroll matthew-carroll merged commit 9cef8f7 into superlistapp:main Apr 22, 2024
11 checks passed
@matthew-carroll
Copy link
Contributor

@angelosilvestre it looks like the cherry pick failed here. Can you do it manually?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[SuperTextEditor] vertical alignment of list items incorrect when settings line height
2 participants