Skip to content

[Map] Add Marker Icon customization capability #2605

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

Merged
merged 5 commits into from
Mar 18, 2025

Conversation

sblondeau
Copy link
Contributor

@sblondeau sblondeau commented Feb 25, 2025

Q A
Bug fix? no
New feature? yes
Issues Fix #2109
License MIT

A nicely asked feature, adding Marker icon customization, it can be an UX Icon, an URL, or a SVG content:

// It can be a UX Icon (requires `symfony/ux-icons` package)...
$icon = Icon::ux('fa:map-marker')->width(24)->height(24);
// ... or an URL pointing to an image
$icon = Icon::url('https://example.com/marker.png')->width(24)->height(24);
// ... or a plain SVG string
$icon = Icon::svg('<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24">...</svg>');

$map->addMarker(new Marker(
    // ...
    icon: $icon
));

Rendering

image

@sblondeau sblondeau requested a review from Kocal as a code owner February 25, 2025 22:22
@carsonbot carsonbot added Status: Needs Review Needs to be reviewed Feature New Feature labels Feb 25, 2025
@sblondeau sblondeau changed the title Feat/add marker icon [Map] add marker icon Feb 25, 2025
Copy link

github-actions bot commented Feb 25, 2025

📊 Packages dist files size difference

Thanks for the PR! Here is the difference in size of the packages dist files between the base branch and the PR.
Please review the changes and make sure they are expected.

FileBefore (Size / Gzip)After (Size / Gzip)
Map
abstract_map_controller.d.ts 4.43 kB / 1023 B 4.95 kB+12% 📈 / 1.15 kB+15% 📈
abstract_map_controller.js 3.88 kB / 1.02 kB 3.97 kB+2% 📈 / 1.07 kB+4% 📈
Map (Bridge Google)
map_controller.d.ts 2.55 kB / 794 B 2.73 kB+7% 📈 / 828 B+4% 📈
map_controller.js 10.16 kB / 2.25 kB 11.16 kB+10% 📈 / 2.52 kB+12% 📈
Map (Bridge Leaflet)
map_controller.d.ts 1.9 kB / 647 B 2.03 kB+7% 📈 / 667 B+3% 📈
map_controller.js 8.58 kB / 2.37 kB 9.63 kB+12% 📈 / 2.58 kB+9% 📈

@sblondeau sblondeau force-pushed the feat/add-marker-icon branch from e7f3fb1 to 721e596 Compare February 25, 2025 22:25
@Kocal
Copy link
Member

Kocal commented Feb 25, 2025

Hey, and thanks for the PR!
I didn't look at the code yet, but by any chance did you see #2109? we had discussed a lot about what we wanted and how.

Thanks!

@sblondeau
Copy link
Contributor Author

Hey, and thanks for the PR! I didn't look at the code yet, but by any chance did you see #2109? we had discussed a lot about what we wanted and how.

Thanks!

I have read it some time ago. I have kept in mind that we should be able to use image url OR svg (OR directly Ux-icon). It was the goal, but maybe I only did a small first step ;-)

@sblondeau sblondeau force-pushed the feat/add-marker-icon branch 2 times, most recently from a7dd42e to 100deca Compare March 3, 2025 21:42
@Kocal Kocal added the Map label Mar 4, 2025
Copy link
Member

@Kocal Kocal left a comment

Choose a reason for hiding this comment

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

Thanks for working on this!

About the IconFactory, we want to keep things simple to use for the user, and so we should not expose it to the user. Instead, we can create Icon named constructor:

  • Icon::fromUrl(url: string, width: int, height: int)
  • Icon::fromInlineSvg(html: string, width: int, height: int)
  • Icon::fromUxIcon(name: string, width: int, height: int)

For each named constructor, I think we must create distinct child classes like Icon\Url, Icon\InlineSvg, Icon\Ux, to keep things cleaner, and it will also helps for later...

Finally, to render a Icon\Ux with the UxIconRenderer, I think it should be done at rendering time in \Symfony\UX\Map\Renderer\AbstractRenderer::getMapAttributes(), or maybe a bit before, to transform an Icon\Ux to Icon\InlineSvg.

Thanks!

@carsonbot carsonbot added Status: Needs Work Additional work is needed and removed Status: Needs Review Needs to be reviewed labels Mar 4, 2025
@sblondeau sblondeau force-pushed the feat/add-marker-icon branch from 100deca to 3db80b6 Compare March 12, 2025 19:45
@carsonbot carsonbot added Status: Needs Review Needs to be reviewed and removed Status: Needs Work Additional work is needed labels Mar 12, 2025
@sblondeau sblondeau force-pushed the feat/add-marker-icon branch 2 times, most recently from 31780fa to d4c98c0 Compare March 12, 2025 21:13
@sblondeau
Copy link
Contributor Author

@Kocal thanks for the review, I've just send an update. Let me know if you have other remarks.
A test is still failing, but it's in TwigComponent, I do not understand why, if you have any idea...
Thanks :-)

@sblondeau sblondeau requested a review from Kocal March 13, 2025 21:33
Copy link
Member

@Kocal Kocal left a comment

Choose a reason for hiding this comment

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

Thanks, it's not far from being perfect, just a last round and it should be fine

Comment on lines 95 to 98
if (null !== $this->uxIconRenderer && null !== $marker['icon'] && 'ux-icon' === $marker['icon']['type']) {
$attrs['markers'][$key]['icon']['content'] = $this->uxIconRenderer->render($marker['icon']['content']);
$attrs['markers'][$key]['icon']['type'] = 'inline-svg';
}
Copy link
Member

Choose a reason for hiding this comment

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

I believe we want to throw an error if the user wanted to use an UxIcon but without symfony/ux-icons, wdyt?

Suggested change
if (null !== $this->uxIconRenderer && null !== $marker['icon'] && 'ux-icon' === $marker['icon']['type']) {
$attrs['markers'][$key]['icon']['content'] = $this->uxIconRenderer->render($marker['icon']['content']);
$attrs['markers'][$key]['icon']['type'] = 'inline-svg';
}
if (UxIcon::TYPE === ($marker['icon']['type'] ?? null)) {
if (!$this->uxIconRenderer) {
throw new ...;
}
$attrs['markers'][$key]['icon']['content'] = $this->uxIconRenderer->render($marker['icon']['content']);
$attrs['markers'][$key]['icon']['type'] = InlineSvg::TYPE;
}

Copy link
Member

Choose a reason for hiding this comment

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

(and it requires to add TYPE constants to InlineSvg, UxIcon, etc.. classes, we don't want to hardcode them)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We already throw a similar exception in UxIconRenderer, it might be redundant ?

Copy link
Member

Choose a reason for hiding this comment

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

But so, $uxIconRenderer property does not need to be nullable right?

@carsonbot carsonbot added Status: Needs Work Additional work is needed and removed Status: Needs Review Needs to be reviewed labels Mar 15, 2025
@Kocal
Copy link
Member

Kocal commented Mar 15, 2025

Don't worry for the failing check on TwigComponent, that's not related

@carsonbot carsonbot added Status: Needs Review Needs to be reviewed and removed Status: Needs Work Additional work is needed labels Mar 15, 2025
@sblondeau sblondeau force-pushed the feat/add-marker-icon branch from 3248cb5 to 704617a Compare March 15, 2025 18:12
@sblondeau sblondeau force-pushed the feat/add-marker-icon branch from 704617a to dd20dbe Compare March 15, 2025 19:08
@sblondeau sblondeau requested a review from Kocal March 15, 2025 19:14
@Kocal Kocal changed the title [Map] add marker icon [Map] Add Marker Icon customization capability Mar 17, 2025
@Kocal
Copy link
Member

Kocal commented Mar 17, 2025

I've pull your PR locally and played a bit with what you've done, but unfortunately some things are broken:

  • on Leaflet, there is a white square around SVG icons, IIRC that's because it uses a default CSS class that we should override:
image
  • it does not render anything on Google Maps, due to an error Cannot read properties of undefined (reading 'parseFromString'):
Capture d’écran 2025-03-17 à 11 35 46

There are also some changes that were not totally applied, don't worry I'm on it!

@Kocal Kocal force-pushed the feat/add-marker-icon branch from b4a6a8f to 311689c Compare March 17, 2025 20:12
@Kocal
Copy link
Member

Kocal commented Mar 17, 2025

PR's description updated

@Kocal
Copy link
Member

Kocal commented Mar 18, 2025

I reworked many minor things (see commits), here is what the following code renders:

$map = (new Map())
    ->center(new Point(48.8566, 2.3522))
    ->zoom(6)
;

$cities = require_once __DIR__.'/../../config/cities.php';
foreach (array_slice($cities, 0, 500) as $i => $city) {
    $map->addMarker(new Marker(
        position: new Point($city['latitude'], $city['longitude']),
        title: $city['label'],
        icon: match(true) {
            $i < 150 => Icon::ux('fa:map-marker'),
            $i < 325 => Icon::url('https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/icons/geo-alt.svg'),
            default => Icon::svg(file_get_contents(__DIR__.'/../../assets/icons/el/map-marker.svg')),
        }
        
    ));
}

For Google Capture d’écran 2025-03-17 à 23 30 17
and LeafletCapture d’écran 2025-03-17 à 23 30 02

I will merge tomorrow I think

@sblondeau
Copy link
Contributor Author

Great job @Kocal ! Thanks for this final touch :)

@Kocal Kocal force-pushed the feat/add-marker-icon branch 9 times, most recently from b0c8144 to 3ee6627 Compare March 18, 2025 17:39
@Kocal Kocal force-pushed the feat/add-marker-icon branch from 3ee6627 to c4f9828 Compare March 18, 2025 17:42
@carsonbot carsonbot added Status: Reviewed Has been reviewed by a maintainer and removed Status: Needs Review Needs to be reviewed labels Mar 18, 2025
@Kocal
Copy link
Member

Kocal commented Mar 18, 2025

Thank you @sblondeau.

@Kocal Kocal merged commit 3f43338 into symfony:2.x Mar 18, 2025
78 of 81 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature New Feature Map Status: Reviewed Has been reviewed by a maintainer
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[UX Map] Allow to customize the marker icon
3 participants