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

Add vertical-align in format expression #900

Open
wants to merge 20 commits into
base: main
Choose a base branch
from

Conversation

stanislawpuda-tomtom
Copy link

@stanislawpuda-tomtom stanislawpuda-tomtom commented Nov 13, 2024

Related issue #832.

This PR introduces vertical align property to format expression. It enables to specify how each section should be positioned in relation to biggest element in line. There are three possible options:

  • "bottom" default: text baseline or image bottom are in line - this is current behaviour.
  • "center": image center or text center are in line.
  • "top": image top and text top are in line

Launch Checklist

  • Confirm your changes do not include backports from Mapbox projects (unless with compliant license) - if you are not sure about this, please ask!
  • Briefly describe the changes in this PR.
  • Link to related issues.
  • Include before/after visuals or gifs if this PR includes visual changes.
  • Write tests for all new functionality.
  • Document any changes to public APIs.
  • Post benchmark scores.
  • Add an entry to CHANGELOG.md under the ## main section.

@codecov-commenter
Copy link

codecov-commenter commented Nov 13, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 92.80%. Comparing base (c6fd205) to head (f2595e9).
Report is 26 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #900      +/-   ##
==========================================
+ Coverage   92.78%   92.80%   +0.01%     
==========================================
  Files         107      107              
  Lines        4739     4752      +13     
  Branches     1346     1352       +6     
==========================================
+ Hits         4397     4410      +13     
  Misses        342      342              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@stanislawpuda-tomtom
Copy link
Author

I would like to cover questions from the meeting on Nov 13th:

Using HTML

I did check, and it is possible to use HTML to display vertically aligned labels. This approach works for MapLibre GL JS, however it does not cover multiple platforms. There are more advantages of using format expression over custom HTML layer:

  • much easier to use
  • HTML markers don't support collision detection, as far as I know, which makes the implementation even more difficult
  • better performance
  • defined once in the style spec for multiple platforms

Format expression already gives possibility to create rich labels on the map, easily, without having to implement own custom solution. Having the possibility to align elements vertically in my opinion is good supplement to format expression. In some cases necessary to make full benefit from it.

Sample use case

Our team created a sample mock how the labels look like with and without vertical alignment.

Before:
before

After:
after

@lseelenbinder
Copy link
Member

Thanks for taking the time to work through these pieces @stanislawpuda-tomtom!

In my opinion, those advantages are sufficient to merit including in the spec—especially for collision detection and performance reasons.

@stanislawpuda-tomtom
Copy link
Author

I have changed baseline to bottom.
I also modified one test to check if vertical-align is recognised for image section.

@HarelM
Copy link
Collaborator

HarelM commented Nov 28, 2024

Are you sure about the places where you added the code?
It seems that equivalent format related code does not look the same.
I know this is an enum while the others are string, or number, but I find the code a bit weird...

@stanislawpuda-tomtom
Copy link
Author

stanislawpuda-tomtom commented Nov 28, 2024

I've added vertical-align to SDK support table.

Screenshot 2024-11-28 at 11 57 56

For the code, let me try to explain:

let verticalAlign = null;
if (arg['vertical-align']) { 
    // covers case, when `vertical-align` is defined with plain string, then we can check if matches enum
    if (typeof arg['vertical-align'] === 'string' && !VERTICAL_ALIGN_OPTIONS.includes(arg['vertical-align'] as VerticalAlign)) {
        return context.error(`\`vertical-align\` must be one of: 'bottom', 'center', 'top' but found '${arg['vertical-align']}' instead.`) as null;
    }

    // in this case it returns expression, so we can't check if it matches enum, only if it is string
    verticalAlign = context.parse(arg['vertical-align'], 1, StringType);
    if (!verticalAlign) return null;
}

src/expression/definitions/format.ts Outdated Show resolved Hide resolved
src/reference/v8.json Outdated Show resolved Hide resolved
@stanislawpuda-tomtom
Copy link
Author

@HarelM @lseelenbinder
Is it possible to proceed with this PR? Is there something I can do, clarify, or is there any blocker?

src/reference/v8.json Outdated Show resolved Hide resolved
@HarelM
Copy link
Collaborator

HarelM commented Dec 9, 2024

I've added details on my concerns regarding the current code. Let me know if this is clearer now.

@stanislawpuda-tomtom
Copy link
Author

@HarelM It is clear - I'll cover them. Thank you!

@stanislawpuda-tomtom
Copy link
Author

@HarelM

I answered your comments.

@HarelM
Copy link
Collaborator

HarelM commented Dec 16, 2024

Thanks, I'll look into it in the coming days.

@HarelM
Copy link
Collaborator

HarelM commented Dec 18, 2024

@louwers can you please review the v8 changes to make sure this is acceptable by you as well?

@HarelM HarelM requested a review from louwers December 18, 2024 09:55
@louwers
Copy link
Collaborator

louwers commented Dec 18, 2024

@HarelM Will have a look.

@@ -3226,10 +3226,10 @@
}
},
"format": {
"doc": "Returns a `formatted` string for displaying mixed-format text in the `text-field` property. The input may contain a string literal or expression, including an [`'image'`](#image) expression. Strings may be followed by a style override object that supports the following properties:\n\n- `\"text-font\"`: Overrides the font stack specified by the root layout property.\n\n- `\"text-color\"`: Overrides the color specified by the root paint property.\n\n- `\"font-scale\"`: Applies a scaling factor on `text-size` as specified by the root layout property.\n\n - [Change the case of labels](https://maplibre.org/maplibre-gl-js/docs/examples/change-case-of-labels/)\n\n - [Display and style rich text labels](https://maplibre.org/maplibre-gl-js/docs/examples/display-and-style-rich-text-labels/)",
"doc": "Returns a `formatted` string for displaying mixed-format text in the `text-field` property. The input may contain a string literal or expression, including an [`'image'`](#image) expression. Strings may be followed by a style override object that supports the following properties:\n\n- `\"text-font\"`: Overrides the font stack specified by the root layout property.\n\n- `\"text-color\"`: Overrides the color specified by the root paint property.\n\n- `\"font-scale\"`: Applies a scaling factor on `text-size` as specified by the root layout property.\n\n- `\"vertical-align\"`: Aligns vertically text section or image in relation to the row it belongs to. Possible values are: \n\t- `\"bottom\"` *default*: text baseline or image bottom are in line.\n\t- `\"center\"`: image center or text center are in line.\n\t- `\"top\"`: image top and text top are in line.\n\n - [Change the case of labels](https://maplibre.org/maplibre-gl-js/docs/examples/change-case-of-labels/)\n\n - [Display and style rich text labels](https://maplibre.org/maplibre-gl-js/docs/examples/display-and-style-rich-text-labels/)",
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think the wording is unclear here for someone not familiar with the design proposal.

image top and text top are in line.

What does image "image top" and "text top" mean here? Better wording would be Align this section of the formatted string so that the top of this section is in line with the top of the other sections. And similarly for the other descriptions.

Choose a reason for hiding this comment

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

Good point, done. I simplified the text you've proposed a bit:
Screenshot 2024-12-23 at 07 01 35

@@ -3226,10 +3226,10 @@
}
},
"format": {
"doc": "Returns a `formatted` string for displaying mixed-format text in the `text-field` property. The input may contain a string literal or expression, including an [`'image'`](#image) expression. Strings may be followed by a style override object that supports the following properties:\n\n- `\"text-font\"`: Overrides the font stack specified by the root layout property.\n\n- `\"text-color\"`: Overrides the color specified by the root paint property.\n\n- `\"font-scale\"`: Applies a scaling factor on `text-size` as specified by the root layout property.\n\n - [Change the case of labels](https://maplibre.org/maplibre-gl-js/docs/examples/change-case-of-labels/)\n\n - [Display and style rich text labels](https://maplibre.org/maplibre-gl-js/docs/examples/display-and-style-rich-text-labels/)",
"doc": "Returns a `formatted` string for displaying mixed-format text in the `text-field` property. The input may contain a string literal or expression, including an [`'image'`](#image) expression. Strings may be followed by a style override object that supports the following properties:\n\n- `\"text-font\"`: Overrides the font stack specified by the root layout property.\n\n- `\"text-color\"`: Overrides the color specified by the root paint property.\n\n- `\"font-scale\"`: Applies a scaling factor on `text-size` as specified by the root layout property.\n\n- `\"vertical-align\"`: Aligns vertically text section or image in relation to the row it belongs to. Possible values are: \n\t- `\"bottom\"` *default*: text baseline or image bottom are in line.\n\t- `\"center\"`: image center or text center are in line.\n\t- `\"top\"`: image top and text top are in line.\n\n - [Change the case of labels](https://maplibre.org/maplibre-gl-js/docs/examples/change-case-of-labels/)\n\n - [Display and style rich text labels](https://maplibre.org/maplibre-gl-js/docs/examples/display-and-style-rich-text-labels/)",
"example": {
Copy link
Collaborator

@louwers louwers Dec 18, 2024

Choose a reason for hiding this comment

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

The example should be updated to include a vertical-align section.

Ideally we would include the images from the design proposal.

If that is difficult for some reason, please update the design proposal with the latest modifications (i.e. use bottom instead of baseline and link to it so people have some additional context and visuals.

Choose a reason for hiding this comment

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

I have updated the example:
Screenshot 2024-12-23 at 07 23 35

I also referenced design proposal. It is updated to use bottom instead of baseline.
Screenshot 2024-12-23 at 07 23 27

For the images - technically I can do it (it works) however there are no images in Expression documentation at all. I'm not sure what is a pattern here. Also I think it is good that expressions documentation is concise, and I'm not sure if adding images won't change that. I think it will be the most valuable to add or update example after maplibre-gl-js implementation. What do you think?

Copy link
Collaborator

@louwers louwers left a comment

Choose a reason for hiding this comment

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

Left two comments. LGTM otherwise.

Also thanks for asking the MapLibre Native community for their feedback. Appreciate it!

@stanislawpuda-tomtom
Copy link
Author

@louwers

Answered. Thank you for your comments.

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.

6 participants