Skip to content

[LiveComponent] add LiveProp name to modifier function #2652

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

Closed
wants to merge 58 commits into from
Closed
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
09b1d86
[LiveComponent] add LiveProp name to modifier function
jannes-io Mar 23, 2025
208952b
Add Twig Extensions for page refreshes
seb-jean Mar 2, 2025
2197b93
[Map] Make renderer tests way easier to maintain, use snapshots
Kocal Mar 25, 2025
79113fe
chore: Adjust changelog for features moving to 2.24 release
zak39 Apr 1, 2025
67eb6b5
improve setup instructions
dbu Mar 29, 2025
cb989bb
[Notify] Added body, icon, tag ,renotify to controller.js for mercure…
May 17, 2024
1fc98e5
[Icons] Add xmlns attribute to svg icons
Enz000 Mar 27, 2025
adf15e7
[Turbo] Add support for authentication to the EventSource via `turbo_…
Fan2Shrek Dec 12, 2024
cb6054e
Update versions to 2.24.0
Kocal Apr 5, 2025
a25cca5
remove banner
kbond Apr 5, 2025
bda797f
[CI] Fix version bump for npm packages
Kocal Apr 5, 2025
9af4c3e
[CI] Use git diff instead of git status
smnandre Apr 9, 2025
f42d00f
Add .editorconfig, enforce LF line-ending style
Kocal Apr 11, 2025
b68a52f
[Turbo] Minor documentation syntax fixes
seb-jean Apr 11, 2025
898953e
[CI] Adjust tags to "v2.*.*" for NPM auto-releases
Kocal Apr 7, 2025
62978fa
[Icons] improve DX when `symfony/http-client` is not installed
kbond Apr 5, 2025
54da4dd
[LiveComponent] Add uid support for hydration
norkunas Mar 24, 2025
67f9389
[Map] Downgrade PHP requirement from 8.3 to 8.1
Kocal Apr 15, 2025
44dbe5c
Pass topics to mercure if not defined
Fan2Shrek Apr 14, 2025
13dfc84
[LiveComponent] `ComponentWithFormTrait` now correctly checks for a `…
stehled Mar 6, 2025
8233dae
[Autocomplete] Escape `querySelector` dynamic selector with `CSS.esca…
Bartheyrman22 Mar 3, 2025
2392dbf
[StimulusBundle] Make the JS package private
Kocal May 3, 2025
db81f8a
[Toolkit] Adds engine for parsing, downloading and manage components
Halleck45 Mar 7, 2025
03ee49c
[Toolkit] Adds first components
Halleck45 Mar 7, 2025
299ba41
[Toolkit] Updated documentation in order to preview components
Halleck45 Mar 7, 2025
0c32931
[Toolkit] Fine-tune the documentation
Kocal Mar 27, 2025
7990353
[Toolkit] Remove "Grid" component
Kocal Mar 28, 2025
fa8be73
[Toolkit] Open dependencies constraints
Kocal Mar 28, 2025
f2d56ac
[Toolkit] Fix UXToolkitBundle name, refactor DependencyInjection/* in…
Kocal Mar 28, 2025
ec4acbe
[Toolkit] Big refactoring about the registry & kits system, kits arch…
Kocal Mar 31, 2025
42940f8
[Toolkit] Rework all components for Shadcn kit, add more, remove some…
Kocal Apr 10, 2025
7525823
[Toolkit] Rework the documentation
Kocal Mar 31, 2025
284144d
[Toolkit] Remove tales-from-a-dev/twig-tailwind-extra dependency, to …
Kocal Apr 15, 2025
a5f8a57
[Toolkit] Refactor `ToolkitKit` enum to `ToolkitKitId`, leverage desc…
Kocal Apr 16, 2025
0b9bc26
[Toolkit] Add StimulusController support, extract logic to KitSynchro…
Kocal May 1, 2025
c5e763d
[Toolkit] Update version handling in dependencies to use string forma…
Kocal May 2, 2025
d648b2c
[Toolkit] Do not use FileSystem::readFile(), as it has been implement…
Kocal May 2, 2025
134e1eb
[Toolkit] Improve InstallComponentCommand by asking/guessing which Ki…
Kocal May 3, 2025
2368fef
[StimulusBundle] Make the JS package private (for real)
Kocal May 6, 2025
98dec2a
[ToolKit] Add missing Interface suffixes
smnandre May 6, 2025
a0f5379
[Toolkit] Fix deprecation Kernel > 7.3
smnandre May 6, 2025
c9e0f4f
[Toolkit] Remove redundant code in Shadcn kit components
Kocal May 5, 2025
726305e
[Site] Rename CodePreview_Tabs to Toolkit_Tabs, extract Toolkit's doc…
Kocal May 5, 2025
c987f60
[Site] Add manual installation steps for Toolkit kits's components
Kocal May 5, 2025
d2086da
[Site] Fix Terminal component styles, ensure it does not grow, and di…
Kocal May 6, 2025
ae4d71d
[Site] Refactor and use the CodeBlockRenderer::highlightCode() method…
Kocal May 6, 2025
26c44dc
[Docs] Add step to disable `package.json` synchronization while upgra…
Kocal Apr 21, 2025
8cb5384
[Toolkit] Introduce KitContextRunner, to run code in the context of a…
Kocal May 8, 2025
ae50fa4
[Toolkit] Add functional tests to render all Kit components usage cod…
Kocal May 8, 2025
d080144
[Toolkit] Remove documentation about non-existant component AlertDial…
Kocal May 8, 2025
c4dcce6
[Toolkit] Pin symfony/phpunit-bridge to ^7.2 and phpunit to ^9.6.22
Kocal May 8, 2025
087f09c
[Toolkit] Remove checks layers for tales-from-a-dev/twig-tailwind-ext…
Kocal May 8, 2025
1282995
[Toolkit] Minor adjustements on Kit creation command (reword question…
Kocal May 11, 2025
05726a6
[Toolkit] Remove Kit "authors"
Kocal May 11, 2025
7591e98
[Toolkit] Improve descriptions of Shadcn components
Kocal May 11, 2025
fc9d51e
fix: allow LiveComponentHydrator::hydrateValue() to hydrate null values
nikophil May 13, 2025
c88678c
[Toolkit] Update snapshots & fix tests, following #2728
Kocal May 13, 2025
ad75701
[TwigComponent] Fix `loadTemplate` deprecation for Twig >= 3.21
smnandre May 6, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
13 changes: 13 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
; top-most EditorConfig file
root = true

; Unix-style newlines
[*]
charset = utf-8
end_of_line = LF
insert_final_newline = true
trim_trailing_whitespace = true

[*.{php,html,twig}]
indent_style = space
indent_size = 4
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
* text=auto eol=lf
/.yarn/** linguist-vendored
/.yarn/releases/* binary
/.yarn/plugins/**/* binary
4 changes: 2 additions & 2 deletions .github/workflows/release-on-npm.yaml
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@ name: Release on NPM
on:
push:
tags:
- 'v*.*.*'
- 'v2.*.*'

jobs:
release:
@@ -32,7 +32,7 @@ jobs:
- run: yarn --immutable

- name: Update version of JS packages
run: yarn workspaces foreach -A version --immediate "${{ env.VERSION }}"
run: yarn workspaces foreach -pA exec "npm version ${{ env.VERSION }} --no-git-tag-version --no-workspaces-update"

- name: Commit changes
run: |
8 changes: 1 addition & 7 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -41,7 +41,7 @@ jobs:

- name: Check if JS dist files are current
run: |
if [[ -n $(git status --porcelain) ]]; then
if ! git diff --quiet; then
echo "The Git workspace is unclean! Changes detected:"
git status --porcelain
git diff
@@ -84,12 +84,6 @@ jobs:
minimum-stability: 'dev'
- php-version: '8.3'
minimum-stability: 'dev'
- component: Map # does not support PHP 8.1
php-version: '8.1'
- component: Map/src/Bridge/Google # does not support PHP 8.1
php-version: '8.1'
- component: Map/src/Bridge/Leaflet # does not support PHP 8.1
php-version: '8.1'
- component: Swup # has no tests
- component: Turbo # has its own workflow (test-turbo.yml)
- component: Typed # has no tests
28 changes: 28 additions & 0 deletions .github/workflows/toolkit-kits-cs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Toolkit Kits

on:
push:
paths:
- 'src/Toolkit/kits/**'
pull_request:
paths:
- 'src/Toolkit/kits/**'

jobs:
kits-cs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: shivammathur/setup-php@v2
with:
php-version: 8.3

- name: Install composer packages
uses: ramsey/composer-install@v3
with:
working-directory: src/Toolkit

- name: Check kits code style
run: php vendor/bin/twig-cs-fixer check kits
working-directory: src/Toolkit
4 changes: 4 additions & 0 deletions src/Autocomplete/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# CHANGELOG

## 2.25.0

- Escape `querySelector` dynamic selector with `CSS.escape()` #2663

## 2.23.0

- Deprecate `ExtraLazyChoiceLoader` in favor of `Symfony\Component\Form\ChoiceList\Loader\LazyChoiceLoader`
2 changes: 2 additions & 0 deletions src/Autocomplete/assets/README.md
Original file line number Diff line number Diff line change
@@ -14,6 +14,8 @@ composer require symfony/ux-autocomplete:2.23.0
npm add @symfony/[email protected]
```

**Tip:** Your `package.json` file will be automatically modified by [Flex](https://github.com/symfony/flex) when installing or upgrading a PHP package. To prevent this behavior, ensure to **use at least Flex 1.22.0 or 2.5.0**, and run `composer config extra.symfony.flex.synchronize_package_json false`.

## Resources

- [Documentation](https://symfony.com/bundles/ux-autocomplete/current/index.html)
54 changes: 27 additions & 27 deletions src/Autocomplete/assets/dist/controller.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
import { Controller } from '@hotwired/stimulus';
import TomSelect from 'tom-select';

/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise, SuppressedError, Symbol */


function __classPrivateFieldGet(receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
}

typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
var e = new Error(message);
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise, SuppressedError, Symbol */


function __classPrivateFieldGet(receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
}

typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
var e = new Error(message);
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
};

var _default_1_instances, _default_1_getCommonConfig, _default_1_createAutocomplete, _default_1_createAutocompleteWithHtmlContents, _default_1_createAutocompleteWithRemoteData, _default_1_stripTags, _default_1_mergeObjects, _default_1_createTomSelect;
@@ -270,7 +270,7 @@ _default_1_instances = new WeakSet(), _default_1_getCommonConfig = function _def
let orderedOption = null;
for (const [, tomSelectOption] of Object.entries(this.tomSelect.options)) {
if (tomSelectOption.$order === optionOrder) {
orderedOption = parentElement.querySelector(`:scope > option[value="${tomSelectOption[this.tomSelect.settings.valueField]}"]`);
orderedOption = parentElement.querySelector(`:scope > option[value="${CSS.escape(tomSelectOption[this.tomSelect.settings.valueField])}"]`);
break;
}
}
2 changes: 1 addition & 1 deletion src/Autocomplete/assets/package.json
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
"name": "@symfony/ux-autocomplete",
"description": "JavaScript Autocomplete functionality for Symfony",
"license": "MIT",
"version": "2.23.0",
"version": "2.24.0",
"keywords": [
"symfony-ux"
],
2 changes: 1 addition & 1 deletion src/Autocomplete/assets/src/controller.ts
Original file line number Diff line number Diff line change
@@ -192,7 +192,7 @@ export default class extends Controller {
for (const [, tomSelectOption] of Object.entries(this.tomSelect.options)) {
if (tomSelectOption.$order === optionOrder) {
orderedOption = parentElement.querySelector(
`:scope > option[value="${tomSelectOption[this.tomSelect.settings.valueField]}"]`
`:scope > option[value="${CSS.escape(tomSelectOption[this.tomSelect.settings.valueField])}"]`
);

break;
2 changes: 2 additions & 0 deletions src/Chartjs/assets/README.md
Original file line number Diff line number Diff line change
@@ -14,6 +14,8 @@ composer require symfony/ux-chartjs:2.23.0
npm add @symfony/[email protected]
```

**Tip:** Your `package.json` file will be automatically modified by [Flex](https://github.com/symfony/flex) when installing or upgrading a PHP package. To prevent this behavior, ensure to **use at least Flex 1.22.0 or 2.5.0**, and run `composer config extra.symfony.flex.synchronize_package_json false`.

## Resources

- [Documentation](https://symfony.com/bundles/ux-chartjs/current/index.html)
2 changes: 1 addition & 1 deletion src/Chartjs/assets/package.json
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
"name": "@symfony/ux-chartjs",
"description": "Chart.js integration for Symfony",
"license": "MIT",
"version": "2.23.0",
"version": "2.24.0",
"keywords": [
"symfony-ux"
],
2 changes: 2 additions & 0 deletions src/Cropperjs/assets/README.md
Original file line number Diff line number Diff line change
@@ -14,6 +14,8 @@ composer require symfony/ux-cropperjs:2.23.0
npm add @symfony/[email protected]
```

**Tip:** Your `package.json` file will be automatically modified by [Flex](https://github.com/symfony/flex) when installing or upgrading a PHP package. To prevent this behavior, ensure to **use at least Flex 1.22.0 or 2.5.0**, and run `composer config extra.symfony.flex.synchronize_package_json false`.

## Resources

- [Documentation](https://symfony.com/bundles/ux-cropperjs/current/index.html)
2 changes: 1 addition & 1 deletion src/Cropperjs/assets/package.json
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
"name": "@symfony/ux-cropperjs",
"description": "Cropper.js integration for Symfony",
"license": "MIT",
"version": "2.23.0",
"version": "2.24.0",
"keywords": [
"symfony-ux"
],
2 changes: 2 additions & 0 deletions src/Dropzone/assets/README.md
Original file line number Diff line number Diff line change
@@ -14,6 +14,8 @@ composer require symfony/ux-dropzone:2.23.0
npm add @symfony/[email protected]
```

**Tip:** Your `package.json` file will be automatically modified by [Flex](https://github.com/symfony/flex) when installing or upgrading a PHP package. To prevent this behavior, ensure to **use at least Flex 1.22.0 or 2.5.0**, and run `composer config extra.symfony.flex.synchronize_package_json false`.

## Resources

- [Documentation](https://symfony.com/bundles/ux-dropzone/current/index.html)
2 changes: 1 addition & 1 deletion src/Dropzone/assets/package.json
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
"name": "@symfony/ux-dropzone",
"description": "File input dropzones for Symfony Forms",
"license": "MIT",
"version": "2.23.0",
"version": "2.24.0",
"keywords": [
"symfony-ux"
],
10 changes: 10 additions & 0 deletions src/Icons/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# CHANGELOG

## 2.25.0

- Improve DX when `symfony/http-client` is not installed.

## 2.24.0

- Add `xmlns` attribute to icons downloaded with Iconify, to correctly render icons browser as an external file, in SVG editors, and in files explorers or text editors previews.
It **may breaks your pipeline** if you assert on `ux_icon()` or `<twig:ux:icon>` output in your tests, and forgot [to lock your icons](https://symfony.com/bundles/ux-icons/current/index.html#locking-on-demand-icons).
We recommend you to **lock** your icons **before** upgrading to UX Icons 2.24. We also suggest you to to **force-lock** your icons **after** upgrading to UX Icons 2.24, to add the attribute `xmlns` to your icons already downloaded from Iconify.

## 2.20.0

- Add `aliases` configuration option to define icon alternative names.
56 changes: 0 additions & 56 deletions src/Icons/config/iconify.php

This file was deleted.

39 changes: 39 additions & 0 deletions src/Icons/config/services.php
Original file line number Diff line number Diff line change
@@ -11,12 +11,17 @@

namespace Symfony\Component\DependencyInjection\Loader\Configurator;

use Symfony\UX\Icons\Command\ImportIconCommand;
use Symfony\UX\Icons\Command\LockIconsCommand;
use Symfony\UX\Icons\Command\SearchIconCommand;
use Symfony\UX\Icons\Command\WarmCacheCommand;
use Symfony\UX\Icons\IconCacheWarmer;
use Symfony\UX\Icons\Iconify;
use Symfony\UX\Icons\IconRenderer;
use Symfony\UX\Icons\IconRendererInterface;
use Symfony\UX\Icons\Registry\CacheIconRegistry;
use Symfony\UX\Icons\Registry\ChainIconRegistry;
use Symfony\UX\Icons\Registry\IconifyOnDemandRegistry;
use Symfony\UX\Icons\Registry\LocalSvgIconRegistry;
use Symfony\UX\Icons\Twig\IconFinder;
use Symfony\UX\Icons\Twig\UXIconExtension;
@@ -86,5 +91,39 @@
service('.ux_icons.cache_warmer'),
])
->tag('console.command')

->set('.ux_icons.iconify', Iconify::class)
->args([
service('.ux_icons.cache'),
abstract_arg('endpoint'),
service('http_client')->nullOnInvalid(),
])

->set('.ux_icons.iconify_on_demand_registry', IconifyOnDemandRegistry::class)
->args([
service('.ux_icons.iconify'),
])
->tag('ux_icons.registry', ['priority' => -10])

->set('.ux_icons.command.import', ImportIconCommand::class)
->args([
service('.ux_icons.iconify'),
service('.ux_icons.local_svg_icon_registry'),
])
->tag('console.command')

->set('.ux_icons.command.lock', LockIconsCommand::class)
->args([
service('.ux_icons.iconify'),
service('.ux_icons.local_svg_icon_registry'),
service('.ux_icons.icon_finder'),
])
->tag('console.command')

->set('.ux_icons.command.search', SearchIconCommand::class)
->args([
service('.ux_icons.iconify'),
])
->tag('console.command')
;
};
53 changes: 43 additions & 10 deletions src/Icons/doc/index.rst
Original file line number Diff line number Diff line change
@@ -16,6 +16,15 @@ Installation
$ composer require symfony/ux-icons
HTTP Client for On-Demand Icons
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you plan to use provided icon sets, make sure that you have the HTTP client installed:

.. code-block:: terminal
$ composer require symfony/http-client
SVG Icons
---------

@@ -63,15 +72,6 @@ Loading Icons
and embeds the downloaded SVG contents in the template #}
{{ ux_icon('flowbite:user-solid') }}
.. note::

To search and download icons via `ux.symfony.com/icons`_, the ``symfony/http-client``
package must be installed in your application:

.. code-block:: terminal
$ composer require symfony/http-client
The ``ux_icon()`` function defines a second optional argument where you can
define the HTML attributes added to the ``<svg>`` element:

@@ -87,6 +87,15 @@ define the HTML attributes added to the ``<svg>`` element:
Icon Sets
~~~~~~~~~

.. note::

To use icons from icon sets via `ux.symfony.com/icons`_, the ``symfony/http-client``
package must be installed in your application:

.. code-block:: terminal
$ composer require symfony/http-client
There are many icon sets available, each with their own unique style and set of
icons, providing a wide range of icons for different purposes, while maintaining
a consistent look and feel across your application. Here are some of the most
@@ -166,7 +175,7 @@ HTML Syntax

In addition to the ``ux_icon()`` function explained in the previous sections,
this package also supports an alternative HTML syntax based on the ``<twig:ux:icon>``
tag:
tag if the ``symfony/ux-twig-component`` package is installed:

.. code-block:: html

@@ -277,6 +286,18 @@ the report to overwrite existing icons by using the ``--force`` option:
$ php bin/console ux:icons:lock --force
.. caution::

The process to find icons to lock in your Twig templates is imperfect. It
looks for any string that matches the pattern ``something:something`` so
it's probable there will be false positives. This command should not be used
to audit the icons in your templates in an automated way. Add ``-v`` see
*potential* invalid icons:

.. code-block:: terminal
$ php bin/console ux:icons:lock -v
Rendering Icons
---------------

@@ -463,6 +484,18 @@ In production, you can pre-warm the cache by running the following command:
This command looks in all your Twig templates for ``ux_icon()`` calls and
``<twig:ux:icon>`` tags and caches the icons it finds.

.. caution::

The process to find icons to cache in your Twig templates is imperfect. It
looks for any string that matches the pattern ``something:something`` so
it's probable there will be false positives. This command should not be used
to audit the icons in your templates in an automated way. Add ``-v`` see
*potential* invalid icons:

.. code-block:: terminal
$ php bin/console ux:icons:warm-cache -v
.. caution::

Icons that have a name built dynamically will not be cached. It's advised to
5 changes: 5 additions & 0 deletions src/Icons/src/Command/WarmCacheCommand.php
Original file line number Diff line number Diff line change
@@ -45,6 +45,11 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$io->writeln(\sprintf(' Warmed icon <comment>%s</comment>.', $name));
}
},
onFailure: function (string $name, \Exception $e) use ($io) {
if ($io->isVerbose()) {
$io->writeln(\sprintf(' Failed to warm (potential) icon <error>%s</error>.', $name));
}
}
);

$io->success('Icon cache warmed.');
27 changes: 12 additions & 15 deletions src/Icons/src/DependencyInjection/UXIconsExtension.php
Original file line number Diff line number Diff line change
@@ -18,7 +18,6 @@
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
use Symfony\Component\HttpKernel\DependencyInjection\ConfigurableExtension;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\UX\Icons\Iconify;

/**
@@ -87,7 +86,7 @@ public function getConfigTreeBuilder(): TreeBuilder
->end()
->arrayNode('iconify')
->info('Configuration for the remote icon service.')
->{interface_exists(HttpClientInterface::class) ? 'canBeDisabled' : 'canBeEnabled'}()
->canBeDisabled()
->children()
->booleanNode('on_demand')
->info('Whether to download icons "on demand".')
@@ -164,26 +163,24 @@ protected function loadInternal(array $mergedConfig, ContainerBuilder $container
->setArgument(1, $mergedConfig['ignore_not_found'])
;

if ($mergedConfig['iconify']['enabled']) {
$loader->load('iconify.php');
$container->getDefinition('.ux_icons.iconify')
->setArgument(1, $mergedConfig['iconify']['endpoint']);

$container->getDefinition('.ux_icons.iconify')
->setArgument(1, $mergedConfig['iconify']['endpoint']);
$container->getDefinition('.ux_icons.iconify_on_demand_registry')
->setArgument(1, $iconSetAliases);

$container->getDefinition('.ux_icons.iconify_on_demand_registry')
->setArgument(1, $iconSetAliases);
$container->getDefinition('.ux_icons.command.lock')
->setArgument(3, $mergedConfig['aliases'])
->setArgument(4, $iconSetAliases);

$container->getDefinition('.ux_icons.command.lock')
->setArgument(3, $mergedConfig['aliases'])
->setArgument(4, $iconSetAliases);

if (!$mergedConfig['iconify']['on_demand']) {
$container->removeDefinition('.ux_icons.iconify_on_demand_registry');
}
if (!$mergedConfig['iconify']['on_demand'] || !$mergedConfig['iconify']['enabled']) {
$container->removeDefinition('.ux_icons.iconify_on_demand_registry');
}

if (!$container->getParameter('kernel.debug')) {
$container->removeDefinition('.ux_icons.command.import');
$container->removeDefinition('.ux_icons.command.search');
$container->removeDefinition('.ux_icons.command.lock');
}
}
}
21 changes: 21 additions & 0 deletions src/Icons/src/Exception/HttpClientNotInstalledException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\UX\Icons\Exception;

/**
* @author Kevin Bond <kevinbond@gmail.com>
*
* @internal
*/
final class HttpClientNotInstalledException extends \LogicException
{
}
8 changes: 4 additions & 4 deletions src/Icons/src/IconCacheWarmer.php
Original file line number Diff line number Diff line change
@@ -27,8 +27,8 @@ public function __construct(private CacheIconRegistry $registry, private IconFin
}

/**
* @param callable(string,Icon):void|null $onSuccess
* @param callable(string):void|null $onFailure
* @param callable(string,Icon):void|null $onSuccess
* @param callable(string,\Exception):void|null $onFailure
*/
public function warm(?callable $onSuccess = null, ?callable $onFailure = null): void
{
@@ -40,8 +40,8 @@ public function warm(?callable $onSuccess = null, ?callable $onFailure = null):
$icon = $this->registry->get($name, refresh: true);

$onSuccess($name, $icon);
} catch (IconNotFoundException) {
$onFailure($name);
} catch (IconNotFoundException $e) {
$onFailure($name, $e);
}
}
}
34 changes: 23 additions & 11 deletions src/Icons/src/Iconify.php
Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@
use Symfony\Component\HttpClient\ScopingHttpClient;
use Symfony\Contracts\Cache\CacheInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\UX\Icons\Exception\HttpClientNotInstalledException;
use Symfony\UX\Icons\Exception\IconNotFoundException;

/**
@@ -26,6 +27,7 @@
final class Iconify
{
public const API_ENDPOINT = 'https://api.iconify.design';
private const ATTR_XMLNS_URL = 'https://www.w3.org/2000/svg';

// URL must be 500 chars max (iconify limit)
// -39 chars: https://api.iconify.design/XXX.json?icons=
@@ -38,15 +40,10 @@ final class Iconify

public function __construct(
private CacheInterface $cache,
string $endpoint = self::API_ENDPOINT,
?HttpClientInterface $http = null,
private string $endpoint = self::API_ENDPOINT,
private ?HttpClientInterface $httpClient = null,
?int $maxIconsQueryLength = null,
) {
if (!class_exists(HttpClient::class)) {
throw new \LogicException('You must install "symfony/http-client" to use Iconify. Try running "composer require symfony/http-client".');
}

$this->http = ScopingHttpClient::forBaseUri($http ?? HttpClient::create(), $endpoint);
$this->maxIconsQueryLength = min(self::MAX_ICONS_QUERY_LENGTH, $maxIconsQueryLength ?? self::MAX_ICONS_QUERY_LENGTH);
}

@@ -61,7 +58,7 @@ public function fetchIcon(string $prefix, string $name): Icon
throw new IconNotFoundException(\sprintf('The icon "%s:%s" does not exist on iconify.design.', $prefix, $name));
}

$response = $this->http->request('GET', \sprintf('/%s.json?icons=%s', $prefix, $name));
$response = $this->http()->request('GET', \sprintf('/%s.json?icons=%s', $prefix, $name));

if (200 !== $response->getStatusCode()) {
throw new IconNotFoundException(\sprintf('The icon "%s:%s" does not exist on iconify.design.', $prefix, $name));
@@ -89,6 +86,7 @@ public function fetchIcon(string $prefix, string $name): Icon
}

return new Icon($data['icons'][$name]['body'], [
'xmlns' => self::ATTR_XMLNS_URL,
'viewBox' => \sprintf('0 0 %s %s', $width ?? $height, $height ?? $width),
]);
}
@@ -110,7 +108,7 @@ public function fetchIcons(string $prefix, array $names): array
throw new \InvalidArgumentException('The query string is too long.');
}

$response = $this->http->request('GET', \sprintf('/%s.json', $prefix), [
$response = $this->http()->request('GET', \sprintf('/%s.json', $prefix), [
'headers' => [
'Accept' => 'application/json',
],
@@ -136,6 +134,7 @@ public function fetchIcons(string $prefix, array $names): array
$width = $iconData['width'] ?? $data['width'] ??= $this->sets()[$prefix]['width'] ?? null;

$icons[$iconName] = new Icon($iconData['body'], [
'xmlns' => self::ATTR_XMLNS_URL,
'viewBox' => \sprintf('0 0 %d %d', $width ?? $height, $height ?? $width),
]);
}
@@ -155,7 +154,7 @@ public function getIconSets(): array

public function searchIcons(string $prefix, string $query)
{
$response = $this->http->request('GET', '/search', [
$response = $this->http()->request('GET', '/search', [
'query' => [
'query' => $query,
'prefix' => $prefix,
@@ -202,9 +201,22 @@ public function chunk(string $prefix, array $names): iterable
private function sets(): \ArrayObject
{
return $this->sets ??= $this->cache->get('iconify-sets', function () {
$response = $this->http->request('GET', '/collections');
$response = $this->http()->request('GET', '/collections');

return new \ArrayObject($response->toArray());
});
}

private function http(): HttpClientInterface
{
if (isset($this->http)) {
return $this->http;
}

if (!class_exists(HttpClient::class)) {
throw new HttpClientNotInstalledException('You must install "symfony/http-client" to use icons from ux.symfony.com/icons. Try running "composer require symfony/http-client".');
}

return $this->http = ScopingHttpClient::forBaseUri($this->httpClient ?? HttpClient::create(), $this->endpoint);
}
}
10 changes: 8 additions & 2 deletions src/Icons/src/Registry/ChainIconRegistry.php
Original file line number Diff line number Diff line change
@@ -34,10 +34,16 @@ public function get(string $name): Icon
foreach ($this->registries as $registry) {
try {
return $registry->get($name);
} catch (IconNotFoundException) {
} catch (IconNotFoundException $e) {
}
}

throw new IconNotFoundException(\sprintf('Icon "%s" not found.', $name));
$message = \sprintf('Icon "%s" not found.', $name);

if (isset($e)) {
$message .= " {$e->getMessage()}";
}

throw new IconNotFoundException($message, previous: $e ?? null);
}
}
7 changes: 6 additions & 1 deletion src/Icons/src/Registry/IconifyOnDemandRegistry.php
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@

namespace Symfony\UX\Icons\Registry;

use Symfony\UX\Icons\Exception\HttpClientNotInstalledException;
use Symfony\UX\Icons\Exception\IconNotFoundException;
use Symfony\UX\Icons\Icon;
use Symfony\UX\Icons\Iconify;
@@ -36,6 +37,10 @@ public function get(string $name): Icon
}
[$prefix, $icon] = $parts;

return $this->iconify->fetchIcon($this->prefixAliases[$prefix] ?? $prefix, $icon);
try {
return $this->iconify->fetchIcon($this->prefixAliases[$prefix] ?? $prefix, $icon);
} catch (HttpClientNotInstalledException $e) {
throw new IconNotFoundException($e->getMessage());
}
}
}
6 changes: 3 additions & 3 deletions src/Icons/tests/Integration/RenderIconsInTwigTest.php
Original file line number Diff line number Diff line change
@@ -33,8 +33,8 @@ public function testRenderIcons(): void
<li id="fifth"><svg viewBox="0 0 24 24" fill="currentColor" class="h-8 w-8" aria-hidden="true"><path fill-rule="evenodd" d="M7.5 6a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0ZM3.751 20.105a8.25 8.25 0 0 1 16.498 0 .75.75 0 0 1-.437.695A18.683 18.683 0 0 1 12 22.5c-2.786 0-5.433-.608-7.812-1.7a.75.75 0 0 1-.437-.695Z" clip-rule="evenodd"></path></svg></li>
<li id="sixth"><svg viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6" aria-labelledby="foo"><path fill-rule="evenodd" d="M19.916 4.626a.75.75 0 0 1 .208 1.04l-9 13.5a.75.75 0 0 1-1.154.114l-6-6a.75.75 0 0 1 1.06-1.06l5.353 5.353 8.493-12.74a.75.75 0 0 1 1.04-.207Z" clip-rule="evenodd"></path></svg></li>
<li id="seventh"><svg viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6" aria-hidden="true"><path fill-rule="evenodd" d="M19.916 4.626a.75.75 0 0 1 .208 1.04l-9 13.5a.75.75 0 0 1-1.154.114l-6-6a.75.75 0 0 1 1.06-1.06l5.353 5.353 8.493-12.74a.75.75 0 0 1 1.04-.207Z" clip-rule="evenodd"></path></svg></li>
<li id="eighth"><svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><g fill="none"><path fill="currentColor" d="m12 3l7.794 4.5v7.845a2 2 0 0 1-1 1.732L13 20.423a2 2 0 0 1-2 0l-5.794-3.346a2 2 0 0 1-1-1.732V7.5z" opacity=".16"/><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m12 3l7.794 4.5v7.845a2 2 0 0 1-1 1.732L13 20.423a2 2 0 0 1-2 0l-5.794-3.346a2 2 0 0 1-1-1.732V7.5z"/><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 7v5l-4.33 2.5M12 12l4.33 2.5"/></g></svg></li>
<li id="ninth"><svg viewBox="0 0 24 24" fill="currentColor" height="24" width="24" aria-hidden="true"><g fill="none"><path fill="currentColor" d="m12 3l7.794 4.5v7.845a2 2 0 0 1-1 1.732L13 20.423a2 2 0 0 1-2 0l-5.794-3.346a2 2 0 0 1-1-1.732V7.5z" opacity=".16"/><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m12 3l7.794 4.5v7.845a2 2 0 0 1-1 1.732L13 20.423a2 2 0 0 1-2 0l-5.794-3.346a2 2 0 0 1-1-1.732V7.5z"/><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 7v5l-4.33 2.5M12 12l4.33 2.5"/></g></svg></li>
<li id="eighth"><svg xmlns="https://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><g fill="none"><path fill="currentColor" d="m12 3l7.794 4.5v7.845a2 2 0 0 1-1 1.732L13 20.423a2 2 0 0 1-2 0l-5.794-3.346a2 2 0 0 1-1-1.732V7.5z" opacity=".16"/><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m12 3l7.794 4.5v7.845a2 2 0 0 1-1 1.732L13 20.423a2 2 0 0 1-2 0l-5.794-3.346a2 2 0 0 1-1-1.732V7.5z"/><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 7v5l-4.33 2.5M12 12l4.33 2.5"/></g></svg></li>
<li id="ninth"><svg xmlns="https://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" height="24" width="24" aria-hidden="true"><g fill="none"><path fill="currentColor" d="m12 3l7.794 4.5v7.845a2 2 0 0 1-1 1.732L13 20.423a2 2 0 0 1-2 0l-5.794-3.346a2 2 0 0 1-1-1.732V7.5z" opacity=".16"/><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m12 3l7.794 4.5v7.845a2 2 0 0 1-1 1.732L13 20.423a2 2 0 0 1-2 0l-5.794-3.346a2 2 0 0 1-1-1.732V7.5z"/><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 7v5l-4.33 2.5M12 12l4.33 2.5"/></g></svg></li>
</ul>
HTML,
trim($output)
@@ -49,7 +49,7 @@ public function testRenderAliasIcons(): void
$templateAlias = '<twig:ux:icon name="flowbite:x-outline" />';
$outputAlias = self::getContainer()->get(Environment::class)->createTemplate($templateAlias)->render();

$expected = '<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L17.94 6M18 18L6.06 6"/></svg>';
$expected = '<svg xmlns="https://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L17.94 6M18 18L6.06 6"/></svg>';
$this->assertSame($outputIcon, $expected);
$this->assertSame($outputIcon, $outputAlias);
}
22 changes: 11 additions & 11 deletions src/Icons/tests/Unit/IconifyTest.php
Original file line number Diff line number Diff line change
@@ -29,7 +29,7 @@ public function testFetchIcon(): void
$iconify = new Iconify(
cache: new NullAdapter(),
endpoint: 'https://example.com',
http: new MockHttpClient([
httpClient: new MockHttpClient([
new JsonMockResponse([
'bi' => [],
]),
@@ -47,15 +47,15 @@ public function testFetchIcon(): void
$icon = $iconify->fetchIcon('bi', 'heart');

$this->assertEquals($icon->getInnerSvg(), '<path d="M0 0h24v24H0z" fill="none"/>');
$this->assertEquals($icon->getAttributes(), ['viewBox' => '0 0 24 24']);
$this->assertEquals($icon->getAttributes(), ['viewBox' => '0 0 24 24', 'xmlns' => 'https://www.w3.org/2000/svg']);
}

public function testFetchIconByAlias(): void
{
$iconify = new Iconify(
cache: new NullAdapter(),
endpoint: 'https://example.com',
http: new MockHttpClient([
httpClient: new MockHttpClient([
new JsonMockResponse([
'bi' => [],
]),
@@ -78,7 +78,7 @@ public function testFetchIconByAlias(): void
$icon = $iconify->fetchIcon('bi', 'foo');

$this->assertEquals($icon->getInnerSvg(), '<path d="M0 0h24v24H0z" fill="none"/>');
$this->assertEquals($icon->getAttributes(), ['viewBox' => '0 0 24 24']);
$this->assertEquals($icon->getAttributes(), ['viewBox' => '0 0 24 24', 'xmlns' => 'https://www.w3.org/2000/svg']);
}

public function testFetchIconThrowsWhenIconSetDoesNotExists(): void
@@ -96,7 +96,7 @@ public function testFetchIconUsesIconsetViewBoxHeight(): void
$iconify = new Iconify(
cache: new NullAdapter(),
endpoint: 'https://example.com',
http: new MockHttpClient([
httpClient: new MockHttpClient([
new JsonMockResponse([
'bi' => [
'height' => 17,
@@ -124,7 +124,7 @@ public function testFetchIconThrowsWhenViewBoxCannotBeComputed(): void
$iconify = new Iconify(
cache: new NullAdapter(),
endpoint: 'https://example.com',
http: new MockHttpClient([
httpClient: new MockHttpClient([
new JsonMockResponse([
'bi' => [],
]),
@@ -149,7 +149,7 @@ public function testFetchIconThrowsWhenStatusCodeNot200(): void
$iconify = new Iconify(
cache: new NullAdapter(),
endpoint: 'https://example.com',
http: new MockHttpClient([
httpClient: new MockHttpClient([
new JsonMockResponse([
'bi' => [],
]),
@@ -168,7 +168,7 @@ public function testFetchIcons(): void
$iconify = new Iconify(
cache: new NullAdapter(),
endpoint: 'https://example.com',
http: new MockHttpClient([
httpClient: new MockHttpClient([
new JsonMockResponse([
'bi' => [],
]),
@@ -199,7 +199,7 @@ public function testFetchIconsByAliases(): void
$iconify = new Iconify(
cache: new NullAdapter(),
endpoint: 'https://example.com',
http: new MockHttpClient([
httpClient: new MockHttpClient([
new JsonMockResponse([
'mdi' => [],
]),
@@ -239,7 +239,7 @@ public function testFetchIconsThrowsWithInvalidIconNames(): void
$iconify = new Iconify(
cache: new NullAdapter(),
endpoint: 'https://example.com',
http: new MockHttpClient([
httpClient: new MockHttpClient([
new JsonMockResponse([
'bi' => [],
]),
@@ -256,7 +256,7 @@ public function testFetchIconsThrowsWithTooManyIcons(): void
$iconify = new Iconify(
cache: new NullAdapter(),
endpoint: 'https://example.com',
http: new MockHttpClient([
httpClient: new MockHttpClient([
new JsonMockResponse([
'bi' => [],
]),
2 changes: 2 additions & 0 deletions src/LazyImage/assets/README.md
Original file line number Diff line number Diff line change
@@ -14,6 +14,8 @@ composer require symfony/ux-lazy-image:2.23.0
npm add @symfony/ux-lazy-image@2.23.0
```

**Tip:** Your `package.json` file will be automatically modified by [Flex](https://github.com/symfony/flex) when installing or upgrading a PHP package. To prevent this behavior, ensure to **use at least Flex 1.22.0 or 2.5.0**, and run `composer config extra.symfony.flex.synchronize_package_json false`.

## Resources

- [Documentation](https://symfony.com/bundles/ux-lazy-image/current/index.html)
2 changes: 1 addition & 1 deletion src/LazyImage/assets/package.json
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
"name": "@symfony/ux-lazy-image",
"description": "Lazy image loader and utilities for Symfony",
"license": "MIT",
"version": "2.23.0",
"version": "2.24.0",
"keywords": [
"symfony-ux"
],
7 changes: 7 additions & 0 deletions src/LiveComponent/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# CHANGELOG

## 2.25.0

- Add support for [Symfony UID](https://symfony.com/doc/current/components/uid.html) hydration/dehydration
- `ComponentWithFormTrait` now correctly checks for a `TranslatableInterface` placeholder for `<select>` elements
- Fix `LiveComponentHydrator::hydrateValue()` to hydrate null values
- Add property name as second paramter to LiveProp modifier callback

## 2.23.0

- Allow configuring the secret used to compute fingerprints and checksums.
2 changes: 2 additions & 0 deletions src/LiveComponent/assets/README.md
Original file line number Diff line number Diff line change
@@ -14,6 +14,8 @@ composer require symfony/ux-live-component:2.23.0
npm add @symfony/ux-live-component@2.23.0
```

**Tip:** Your `package.json` file will be automatically modified by [Flex](https://github.com/symfony/flex) when installing or upgrading a PHP package. To prevent this behavior, ensure to **use at least Flex 1.22.0 or 2.5.0**, and run `composer config extra.symfony.flex.synchronize_package_json false`.

## Resources

- [Documentation](https://symfony.com/bundles/ux-live-component/current/index.html)
2 changes: 1 addition & 1 deletion src/LiveComponent/assets/package.json
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
"name": "@symfony/ux-live-component",
"description": "Live Component: bring server-side re-rendering & model binding to any element.",
"license": "MIT",
"version": "2.23.0",
"version": "2.24.0",
"keywords": [
"symfony-ux",
"twig",
1 change: 1 addition & 0 deletions src/LiveComponent/composer.json
Original file line number Diff line number Diff line change
@@ -50,6 +50,7 @@
"symfony/security-bundle": "^5.4|^6.0|^7.0",
"symfony/serializer": "^5.4|^6.0|^7.0",
"symfony/twig-bundle": "^5.4|^6.0|^7.0",
"symfony/uid": "^5.4|^6.0|^7.0",
"symfony/validator": "^5.4|^6.0|^7.0",
"zenstruck/browser": "^1.2.0",
"zenstruck/foundry": "^2.0"
41 changes: 41 additions & 0 deletions src/LiveComponent/doc/index.rst
Original file line number Diff line number Diff line change
@@ -2651,6 +2651,47 @@ This way you can also use the component multiple times in the same page and avoi
<twig:SearchModule alias="q1" />
<twig:SearchModule alias="q2" />

.. versionadded:: 2.25

The property name is passed into the modifier function since LiveComponents 2.25.
Comment on lines +2654 to +2656
Copy link
Contributor Author

@jannes-io jannes-io Apr 6, 2025

Choose a reason for hiding this comment

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

This'd have to be updated to the actual release version, I just took the next one.


The ``modifier`` function can also take the name of the property as a secondary parameter.
It can be used to perform more generic operations inside of the modifier that can be re-used for multiple props::

abstract class AbstractSearchModule
{
#[LiveProp(writable: true, url: true, modifier: 'modifyQueryProp')]
public string $query = '';

protected string $urlPrefix = '';

public function modifyQueryProp(LiveProp $liveProp, string $propName): LiveProp
{
if ($this->urlPrefix) {
return $liveProp->withUrl(new UrlMapping(as: $this->urlPrefix.'-'.$propName));
}
return $liveProp;
}
}

#[AsLiveComponent]
class ImportantSearchModule extends AbstractSearchModule
{
}

#[AsLiveComponent]
class SecondarySearchModule extends AbstractSearchModule
{
protected string $urlPrefix = 'secondary';
}
Comment on lines +2661 to +2686
Copy link
Member

Choose a reason for hiding this comment

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

I'm wondering.. could we find use an example more focused on the feature than the PHP code structure abstract/extends here ?

I was thinking something like "imagine you have a CMS theme editor with a split view allowing you to adjust your design both in light and dark mode. ...

You could use a ColorTheme LiveComponent for both, but then [describe problem]

<twig:ColorSettings prefix="dark" color="..." />

<twig:ColorSettings prefix="light" color="..." />

Thanks to the second parameter of YYY, you can dynamically prefix [...].

    #[LiveProp]
     public string $theme;

     #[LiveProp(url: true, modifier: 'prefixParam')]
     public string $color;

       public function prefixParam($liveProp, string $propName): LiveProp
       {
               return $liveProp->withUrl(
                  // Light Theme will use ?light-color
                   new UrlMapping(as: $this->prefix.'-'.$propName)
              );
       }

Now your query parameters will be: XXX ZZZ

It even works with the as: property ..

     // query param will be ZZZ

      #[LiveProp(url: true, as: 'bg' modifier: 'prefixParam')]
      public string $background;      

wdyt ?


.. code-block:: html+twig

<twig:ImportantSearchModule />
<twig:SecondarySearchModule />

The ``query`` value will appear in the URL like ``/search?query=my+important+query&secondary-query=my+secondary+query``.

Validating the Query Parameter Values
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

4 changes: 3 additions & 1 deletion src/LiveComponent/src/ComponentWithFormTrait.php
Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
use Symfony\Contracts\Translation\TranslatableInterface;
use Symfony\UX\LiveComponent\Attribute\LiveProp;
use Symfony\UX\LiveComponent\Attribute\PreReRender;
use Symfony\UX\LiveComponent\Util\LiveFormUtility;
@@ -286,7 +287,8 @@ private function extractFormValues(FormView $formView): array
)
&& !$child->vars['expanded'] // is a <select> (not a radio/checkbox)
&& !$child->vars['multiple'] // is not multiple
&& !\is_string($child->vars['placeholder']) // has no placeholder (empty string is valid)
&& !\is_string($child->vars['placeholder']) // has no placeholder (empty string is valid)
&& !$child->vars['placeholder'] instanceof TranslatableInterface // has no placeholder (translatable interface is valid)
) {
$choices = $child->vars['preferred_choices'] ?: $child->vars['choices']; // preferred_choices has precedence, as they rendered before regular choices
do {
17 changes: 17 additions & 0 deletions src/LiveComponent/src/LiveComponentHydrator.php
Original file line number Diff line number Diff line change
@@ -22,6 +22,7 @@
use Symfony\Component\Serializer\Exception\ExceptionInterface as SerializerExceptionInterface;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use Symfony\Component\Uid\AbstractUid;
use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
use Symfony\UX\LiveComponent\Attribute\LiveProp;
use Symfony\UX\LiveComponent\Exception\HydrationException;
@@ -281,6 +282,10 @@ public function hydrateValue(mixed $value, LivePropMetadata $propMetadata, objec
throw new \LogicException(\sprintf('The "%s::%s" object should be hydrated with the Serializer, but no type could be guessed.', $parentObject::class, $propMetadata->getName()));
}

if (null === $value && $propMetadata->allowsNull()) {
return null;
}

return $this->serializer->denormalize($value, $type, 'json', $propMetadata->serializationContext());
}

@@ -505,6 +510,10 @@ private function dehydrateObjectValue(object $value, string $classType, ?string
return $value->value;
}

if ($value instanceof AbstractUid) {
return (string) $value;
}

foreach ($this->hydrationExtensions as $extension) {
if ($extension->supports($classType)) {
return $extension->dehydrate($value);
@@ -553,6 +562,14 @@ private function hydrateObjectValue(mixed $value, string $className, bool $allow
return new $className($value);
}

if (is_a($className, AbstractUid::class, true)) {
if (!\is_string($value)) {
throw new BadRequestHttpException(\sprintf('The model path "%s" was sent an invalid data type "%s" for a uuid.', $propertyPathForError, get_debug_type($value)));
}

return $className::fromString($value);
}

foreach ($this->hydrationExtensions as $extension) {
if ($extension->supports($className)) {
return $extension->hydrate($value, $className);
2 changes: 1 addition & 1 deletion src/LiveComponent/src/Metadata/LivePropMetadata.php
Original file line number Diff line number Diff line change
@@ -135,7 +135,7 @@ public function withModifier(object $component): self
throw new \LogicException(\sprintf('Method "%s::%s()" given in LiveProp "modifier" does not exist.', $component::class, $modifier));
}

$modifiedLiveProp = $component->{$modifier}($this->liveProp);
$modifiedLiveProp = $component->{$modifier}($this->liveProp, $this->getName());
Copy link
Member

Choose a reason for hiding this comment

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

For a change like this, a test would be needed. Especially for things related to query, URL, etc.

(The fact tests do pass after your changes does not proves it does work (nor that our current suite of test is good enough, to be fair))

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added to the existing test, I don't see the need to make a separate test for just this param unless there are some edge cases that aren't entirely obvious to me at this time.

Copy link
Member

Choose a reason for hiding this comment

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

Let's test a page with two instances of same component, different prefix used in the modifier ... and check that the correct one as the good value and not the other :)

if (!$modifiedLiveProp instanceof LiveProp) {
throw new \LogicException(\sprintf('Method "%s::%s()" should return an instance of "%s" (given: "%s").', $component::class, $modifier, LiveProp::class, get_debug_type($modifiedLiveProp)));
}
33 changes: 33 additions & 0 deletions src/LiveComponent/tests/Integration/LiveComponentHydratorTest.php
Original file line number Diff line number Diff line change
@@ -13,6 +13,9 @@

use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Uid\Ulid;
use Symfony\Component\Uid\Uuid;
use Symfony\Component\Uid\UuidV4;
use Symfony\UX\LiveComponent\Attribute\LiveProp;
use Symfony\UX\LiveComponent\Exception\HydrationException;
use Symfony\UX\LiveComponent\Metadata\LiveComponentMetadata;
@@ -1372,6 +1375,36 @@ public function modifyDateProp(LiveProp $prop): LiveProp
})
;
}];

yield 'Uuid: (de)hydrates correctly' => [function () {
$uuid = new UuidV4('ffdb229c-13e6-4bc4-939e-c8e73958104c');

return HydrationTest::create(new class {
#[LiveProp]
public Uuid $id;
})
->mountWith(['id' => $uuid])
->assertDehydratesTo(['id' => 'ffdb229c-13e6-4bc4-939e-c8e73958104c'])
->assertObjectAfterHydration(function (object $object) {
self::assertEquals(new UuidV4('ffdb229c-13e6-4bc4-939e-c8e73958104c'), $object->id);
})
;
}];

yield 'Ulid: (de)hydrates correctly' => [function () {
$uuid = new Ulid('01AN4Z07BY79KA1307SR9X4MV3');

return HydrationTest::create(new class {
#[LiveProp]
public Ulid $id;
})
->mountWith(['id' => $uuid])
->assertDehydratesTo(['id' => '01AN4Z07BY79KA1307SR9X4MV3'])
->assertObjectAfterHydration(function (object $object) {
self::assertEquals(new Ulid('01AN4Z07BY79KA1307SR9X4MV3'), $object->id);
})
;
}];
}

public function testHydrationWithInvalidDate(): void
30 changes: 30 additions & 0 deletions src/LiveComponent/tests/Unit/LiveComponentHydratorTest.php
Original file line number Diff line number Diff line change
@@ -14,8 +14,12 @@
use PHPUnit\Framework\TestCase;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;
use Symfony\UX\LiveComponent\Attribute\LiveProp;
use Symfony\UX\LiveComponent\LiveComponentHydrator;
use Symfony\UX\LiveComponent\Metadata\LiveComponentMetadataFactory;
use Symfony\UX\LiveComponent\Metadata\LivePropMetadata;

final class LiveComponentHydratorTest extends TestCase
{
@@ -32,4 +36,30 @@ public function testConstructWithEmptySecret(): void
'',
);
}

public function testItCanHydrateWithNullValues()
{
$hydrator = new LiveComponentHydrator(
[],
$this->createMock(PropertyAccessorInterface::class),
$this->createMock(LiveComponentMetadataFactory::class),
new Serializer(normalizers: [new ObjectNormalizer()]),
'foo',
);

$hydratedValue = $hydrator->hydrateValue(
null,
new LivePropMetadata('foo', new LiveProp(useSerializerForHydration: true), typeName: Foo::class, isBuiltIn: false, allowsNull: true, collectionValueType: null),
parentObject: new \stdClass() // not relevant in this test
);

self::assertNull($hydratedValue);
}
}

class Foo
{
public function __construct(private int $id)
{
}
}
Original file line number Diff line number Diff line change
@@ -29,7 +29,7 @@ public function testWithModifier()
$component
->expects($this->once())
->method('modifyProp')
->with($liveProp)
->with($liveProp, 'propWithModifier')
->willReturn($liveProp->withFieldName('customField'));

$livePropMetadata = $livePropMetadata->withModifier($component);
18 changes: 11 additions & 7 deletions src/Map/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
# CHANGELOG

## 2.25

- Downgrade PHP requirement from 8.3 to 8.1

## 2.24

- Installing the package in a Symfony app using Flex won't add the `@symfony/ux-map` dependency to the `package.json` file anymore.
- Add `Icon` to customize a `Marker` icon (URL or SVG content)
- Add parameter `id` to `Marker`, `Polygon` and `Polyline` constructors
- Add method `Map::removeMarker(string|Marker $markerOrId)`
- Add method `Map::removePolygon(string|Polygon $polygonOrId)`
- Add method `Map::removePolyline(string|Polyline $polylineOrId)`

## 2.23

@@ -12,10 +20,6 @@
- Add `DistanceCalculatorInterface` interface and three implementations:
`HaversineDistanceCalculator`, `SphericalCosineDistanceCalculator` and `VincentyDistanceCalculator`.
- Add `CoordinateUtils` helper, to convert decimal coordinates (`43.2109`) in DMS (`56° 78' 90"`)
- Add parameter `id` to `Marker`, `Polygon` and `Polyline` constructors
- Add method `Map::removeMarker(string|Marker $markerOrId)`
- Add method `Map::removePolygon(string|Polygon $polygonOrId)`
- Add method `Map::removePolyline(string|Polyline $polylineOrId)`

## 2.22

@@ -26,13 +30,13 @@

## 2.20

- Deprecate `render_map` Twig function (will be removed in 2.21). Use
- Deprecate `render_map` Twig function (will be removed in 2.21). Use
`ux_map` or the `<twig:ux:map />` Twig component instead.
- Add `ux_map` Twig function (replaces `render_map` with a more flexible
- Add `ux_map` Twig function (replaces `render_map` with a more flexible
interface)
- Add `<twig:ux:map />` Twig component
- The importmap entry `@symfony/ux-map/abstract-map-controller` can be removed
from your importmap, it is no longer needed.
from your importmap, it is no longer needed.
- Add `Polygon` support

## 2.19
2 changes: 1 addition & 1 deletion src/Map/assets/package.json
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@
"description": "Easily embed interactive maps in your Symfony application.",
"private": true,
"license": "MIT",
"version": "2.23.0",
"version": "2.24.0",
"keywords": [
"symfony-ux",
"map",
4 changes: 2 additions & 2 deletions src/Map/composer.json
Original file line number Diff line number Diff line change
@@ -32,13 +32,13 @@
}
},
"require": {
"php": ">=8.3",
"php": ">=8.1",
"symfony/stimulus-bundle": "^2.18.1"
},
"require-dev": {
"symfony/asset-mapper": "^6.4|^7.0",
"symfony/framework-bundle": "^6.4|^7.0",
"symfony/phpunit-bridge": "^6.4|^7.0",
"symfony/phpunit-bridge": "^7.2",
"symfony/twig-bundle": "^6.4|^7.0",
"symfony/ux-twig-component": "^2.18",
"symfony/ux-icons": "^2.18"
6 changes: 5 additions & 1 deletion src/Map/src/Bridge/Google/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# CHANGELOG

## 2.25

- Downgrade PHP requirement from 8.3 to 8.1

## 2.22

- Add support for configuring a default Map ID
@@ -10,7 +14,7 @@

### BC Breaks

- Renamed importmap entry `@symfony/ux-google-map/map-controller` to `@symfony/ux-google-map`,
- Renamed importmap entry `@symfony/ux-google-map/map-controller` to `@symfony/ux-google-map`,
you will need to update your importmap.

## 2.19
2 changes: 2 additions & 0 deletions src/Map/src/Bridge/Google/assets/README.md
Original file line number Diff line number Diff line change
@@ -14,6 +14,8 @@ composer require symfony/ux-google-map:2.23.0
npm add @symfony/ux-google-map@2.23.0
```

**Tip:** Your `package.json` file will be automatically modified by [Flex](https://github.com/symfony/flex) when installing or upgrading a PHP package. To prevent this behavior, ensure to **use at least Flex 1.22.0 or 2.5.0**, and run `composer config extra.symfony.flex.synchronize_package_json false`.

## Resources

- [Documentation](https://github.com/symfony/ux/tree/2.x/src/Map/src/Bridge/Google)
2 changes: 1 addition & 1 deletion src/Map/src/Bridge/Google/assets/package.json
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
"name": "@symfony/ux-google-map",
"description": "GoogleMaps bridge for Symfony UX Map, integrate interactive maps in your Symfony applications",
"license": "MIT",
"version": "2.23.0",
"version": "2.24.0",
"keywords": [
"symfony-ux",
"google-maps",
8 changes: 5 additions & 3 deletions src/Map/src/Bridge/Google/composer.json
Original file line number Diff line number Diff line change
@@ -16,13 +16,15 @@
}
],
"require": {
"php": ">=8.3",
"php": ">=8.1",
"symfony/stimulus-bundle": "^2.18.1",
"symfony/ux-map": "^2.19"
},
"require-dev": {
"symfony/phpunit-bridge": "^6.4|^7.0",
"symfony/ux-icons": "^2.18"
"symfony/phpunit-bridge": "^7.2",
"symfony/ux-icons": "^2.18",
"spatie/phpunit-snapshot-assertions": "^4.2.17",
"phpunit/phpunit": "^9.6.22"
},
"autoload": {
"psr-4": { "Symfony\\UX\\Map\\Bridge\\Google\\": "src/" },
2 changes: 1 addition & 1 deletion src/Map/src/Bridge/Google/phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@
<directory suffix=".php">./src</directory>
</include>
</coverage>

<php>
<ini name="error_reporting" value="-1"/>
<server name="SYMFONY_DEPRECATIONS_HELPER" value="max[self]=0&amp;max[direct]=0"/>
Original file line number Diff line number Diff line change
@@ -18,10 +18,10 @@
*
* @author Hugo Alliaume <hugo@alliau.me>
*/
final readonly class FullscreenControlOptions
final class FullscreenControlOptions
{
public function __construct(
private ControlPosition $position = ControlPosition::INLINE_END_BLOCK_START,
private readonly ControlPosition $position = ControlPosition::INLINE_END_BLOCK_START,
) {
}

Original file line number Diff line number Diff line change
@@ -18,15 +18,15 @@
*
* @author Hugo Alliaume <hugo@alliau.me>
*/
final readonly class MapTypeControlOptions
final class MapTypeControlOptions
{
/**
* @param array<'hybrid'|'roadmap'|'satellite'|'terrain'|string> $mapTypeIds
*/
public function __construct(
private array $mapTypeIds = [],
private ControlPosition $position = ControlPosition::BLOCK_START_INLINE_START,
private MapTypeControlStyle $style = MapTypeControlStyle::DEFAULT,
private readonly array $mapTypeIds = [],
private readonly ControlPosition $position = ControlPosition::BLOCK_START_INLINE_START,
private readonly MapTypeControlStyle $style = MapTypeControlStyle::DEFAULT,
) {
}

Original file line number Diff line number Diff line change
@@ -18,10 +18,10 @@
*
* @author Hugo Alliaume <hugo@alliau.me>
*/
final readonly class StreetViewControlOptions
final class StreetViewControlOptions
{
public function __construct(
private ControlPosition $position = ControlPosition::INLINE_END_BLOCK_END,
private readonly ControlPosition $position = ControlPosition::INLINE_END_BLOCK_END,
) {
}

4 changes: 2 additions & 2 deletions src/Map/src/Bridge/Google/src/Option/ZoomControlOptions.php
Original file line number Diff line number Diff line change
@@ -18,10 +18,10 @@
*
* @author Hugo Alliaume <hugo@alliau.me>
*/
final readonly class ZoomControlOptions
final class ZoomControlOptions
{
public function __construct(
private ControlPosition $position = ControlPosition::INLINE_END_BLOCK_END,
private readonly ControlPosition $position = ControlPosition::INLINE_END_BLOCK_END,
) {
}

23 changes: 11 additions & 12 deletions src/Map/src/Bridge/Google/src/Renderer/GoogleRenderer.php
Original file line number Diff line number Diff line change
@@ -22,28 +22,27 @@
*
* @internal
*/
final readonly class GoogleRenderer extends AbstractRenderer
final class GoogleRenderer extends AbstractRenderer
{
/**
* Parameters are based from https://googlemaps.github.io/js-api-loader/interfaces/LoaderOptions.html documentation.
*/
public function __construct(
StimulusHelper $stimulusHelper,
UxIconRenderer $uxIconRenderer,
#[\SensitiveParameter]
private string $apiKey,
private ?string $id = null,
private ?string $language = null,
private ?string $region = null,
private ?string $nonce = null,
private ?int $retries = null,
private ?string $url = null,
private ?string $version = null,
#[\SensitiveParameter] private readonly string $apiKey,
private readonly ?string $id = null,
private readonly ?string $language = null,
private readonly ?string $region = null,
private readonly ?string $nonce = null,
private readonly ?int $retries = null,
private readonly ?string $url = null,
private readonly ?string $version = null,
/**
* @var array<'core'|'maps'|'places'|'geocoding'|'routes'|'marker'|'geometry'|'elevation'|'streetView'|'journeySharing'|'drawing'|'visualization'>
*/
private array $libraries = [],
private ?string $defaultMapId = null,
private readonly array $libraries = [],
private readonly ?string $defaultMapId = null,
) {
parent::__construct($stimulusHelper, $uxIconRenderer);
}
16 changes: 1 addition & 15 deletions src/Map/src/Bridge/Google/tests/GoogleRendererTest.php

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- This HTML has been prettified for testing purposes, and may not represent the actual HTML output.
Run "php vendor/bin/phpunit -d --update-snapshots" to update the snapshot. -->
<div
data-controller="symfony--ux-google-map--map"
data-symfony--ux-google-map--map-provider-options-value="{&quot;apiKey&quot;:&quot;my_api_key&quot;}"
data-symfony--ux-google-map--map-center-value="{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522}"
data-symfony--ux-google-map--map-zoom-value="12"
data-symfony--ux-google-map--map-fit-bounds-to-markers-value="false"
data-symfony--ux-google-map--map-options-value="{&quot;mapId&quot;:null,&quot;gestureHandling&quot;:&quot;auto&quot;,&quot;backgroundColor&quot;:null,&quot;disableDoubleClickZoom&quot;:false,&quot;zoomControlOptions&quot;:{&quot;position&quot;:22},&quot;mapTypeControlOptions&quot;:{&quot;mapTypeIds&quot;:[],&quot;position&quot;:14,&quot;style&quot;:0},&quot;streetViewControlOptions&quot;:{&quot;position&quot;:22},&quot;fullscreenControlOptions&quot;:{&quot;position&quot;:20},&quot;@provider&quot;:&quot;google&quot;}"
data-symfony--ux-google-map--map-markers-value="[{&quot;position&quot;:{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522},&quot;title&quot;:&quot;Paris&quot;,&quot;infoWindow&quot;:null,&quot;icon&quot;:{&quot;type&quot;:&quot;url&quot;,&quot;width&quot;:32,&quot;height&quot;:32,&quot;url&quot;:&quot;https:\/\/cdn.jsdelivr.net\/npm\/bootstrap-icons@1.11.3\/icons\/geo-alt.svg&quot;},&quot;extra&quot;:[],&quot;id&quot;:null,&quot;@id&quot;:&quot;217fa57668ad8e64&quot;},{&quot;position&quot;:{&quot;lat&quot;:45.764,&quot;lng&quot;:4.8357},&quot;title&quot;:&quot;Lyon&quot;,&quot;infoWindow&quot;:null,&quot;icon&quot;:{&quot;type&quot;:&quot;ux-icon&quot;,&quot;width&quot;:32,&quot;height&quot;:32,&quot;name&quot;:&quot;fa:map-marker&quot;,&quot;_generated_html&quot;:&quot;&lt;svg xmlns=\&quot;http:\/\/www.w3.org\/2000\/svg\&quot; width=\&quot;24\&quot; height=\&quot;24\&quot;&gt;...&lt;\/svg&gt;&quot;},&quot;extra&quot;:[],&quot;id&quot;:null,&quot;@id&quot;:&quot;255b208136900fc0&quot;},{&quot;position&quot;:{&quot;lat&quot;:45.8566,&quot;lng&quot;:2.3522},&quot;title&quot;:&quot;Dijon&quot;,&quot;infoWindow&quot;:null,&quot;icon&quot;:{&quot;type&quot;:&quot;svg&quot;,&quot;width&quot;:24,&quot;height&quot;:24,&quot;html&quot;:&quot;&lt;svg xmlns=\&quot;http:\/\/www.w3.org\/2000\/svg\&quot; width=\&quot;24\&quot; height=\&quot;24\&quot;&gt;...&lt;\/svg&gt;&quot;},&quot;extra&quot;:[],&quot;id&quot;:null,&quot;@id&quot;:&quot;1a410e92214f770c&quot;}]"
data-symfony--ux-google-map--map-polygons-value="[]"
data-symfony--ux-google-map--map-polylines-value="[]"
></div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- This HTML has been prettified for testing purposes, and may not represent the actual HTML output.
Run "php vendor/bin/phpunit -d --update-snapshots" to update the snapshot. -->
<div
data-controller="symfony--ux-google-map--map"
data-symfony--ux-google-map--map-provider-options-value="{&quot;apiKey&quot;:&quot;api_key&quot;}"
data-symfony--ux-google-map--map-center-value="{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522}"
data-symfony--ux-google-map--map-zoom-value="12"
data-symfony--ux-google-map--map-fit-bounds-to-markers-value="false"
data-symfony--ux-google-map--map-options-value="{&quot;mapId&quot;:null,&quot;gestureHandling&quot;:&quot;auto&quot;,&quot;backgroundColor&quot;:null,&quot;disableDoubleClickZoom&quot;:false,&quot;zoomControlOptions&quot;:{&quot;position&quot;:22},&quot;mapTypeControlOptions&quot;:{&quot;mapTypeIds&quot;:[],&quot;position&quot;:14,&quot;style&quot;:0},&quot;streetViewControlOptions&quot;:{&quot;position&quot;:22},&quot;fullscreenControlOptions&quot;:{&quot;position&quot;:20},&quot;@provider&quot;:&quot;google&quot;}"
data-symfony--ux-google-map--map-markers-value="[]"
data-symfony--ux-google-map--map-polygons-value="[]"
data-symfony--ux-google-map--map-polylines-value="[]"
></div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- This HTML has been prettified for testing purposes, and may not represent the actual HTML output.
Run "php vendor/bin/phpunit -d --update-snapshots" to update the snapshot. -->
<div
data-controller="symfony--ux-google-map--map"
data-symfony--ux-google-map--map-provider-options-value="{&quot;apiKey&quot;:&quot;api_key&quot;}"
data-symfony--ux-google-map--map-center-value="{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522}"
data-symfony--ux-google-map--map-zoom-value="12"
data-symfony--ux-google-map--map-fit-bounds-to-markers-value="false"
data-symfony--ux-google-map--map-options-value="{&quot;mapId&quot;:null,&quot;gestureHandling&quot;:&quot;auto&quot;,&quot;backgroundColor&quot;:null,&quot;disableDoubleClickZoom&quot;:false,&quot;zoomControlOptions&quot;:{&quot;position&quot;:22},&quot;mapTypeControlOptions&quot;:{&quot;mapTypeIds&quot;:[],&quot;position&quot;:14,&quot;style&quot;:0},&quot;streetViewControlOptions&quot;:{&quot;position&quot;:22},&quot;fullscreenControlOptions&quot;:{&quot;position&quot;:20},&quot;@provider&quot;:&quot;google&quot;}"
data-symfony--ux-google-map--map-markers-value="[]"
data-symfony--ux-google-map--map-polygons-value="[]"
data-symfony--ux-google-map--map-polylines-value="[]"
></div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- This HTML has been prettified for testing purposes, and may not represent the actual HTML output.
Run "php vendor/bin/phpunit -d --update-snapshots" to update the snapshot. -->
<div
data-controller="symfony--ux-google-map--map"
data-symfony--ux-google-map--map-provider-options-value="{&quot;apiKey&quot;:&quot;api_key&quot;}"
data-symfony--ux-google-map--map-center-value="{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522}"
data-symfony--ux-google-map--map-zoom-value="12"
data-symfony--ux-google-map--map-fit-bounds-to-markers-value="false"
data-symfony--ux-google-map--map-options-value="{&quot;mapId&quot;:null,&quot;gestureHandling&quot;:&quot;auto&quot;,&quot;backgroundColor&quot;:null,&quot;disableDoubleClickZoom&quot;:false,&quot;zoomControlOptions&quot;:{&quot;position&quot;:22},&quot;mapTypeControlOptions&quot;:{&quot;mapTypeIds&quot;:[],&quot;position&quot;:14,&quot;style&quot;:0},&quot;streetViewControlOptions&quot;:{&quot;position&quot;:22},&quot;fullscreenControlOptions&quot;:{&quot;position&quot;:20},&quot;@provider&quot;:&quot;google&quot;}"
data-symfony--ux-google-map--map-markers-value="[]"
data-symfony--ux-google-map--map-polygons-value="[]"
data-symfony--ux-google-map--map-polylines-value="[]"
></div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!-- This HTML has been prettified for testing purposes, and may not represent the actual HTML output.
Run "php vendor/bin/phpunit -d --update-snapshots" to update the snapshot. -->
<div
data-controller="my-custom-controller symfony--ux-google-map--map"
data-symfony--ux-google-map--map-provider-options-value="{&quot;apiKey&quot;:&quot;api_key&quot;}"
data-symfony--ux-google-map--map-center-value="{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522}"
data-symfony--ux-google-map--map-zoom-value="12"
data-symfony--ux-google-map--map-fit-bounds-to-markers-value="false"
data-symfony--ux-google-map--map-options-value="{&quot;mapId&quot;:null,&quot;gestureHandling&quot;:&quot;auto&quot;,&quot;backgroundColor&quot;:null,&quot;disableDoubleClickZoom&quot;:false,&quot;zoomControlOptions&quot;:{&quot;position&quot;:22},&quot;mapTypeControlOptions&quot;:{&quot;mapTypeIds&quot;:[],&quot;position&quot;:14,&quot;style&quot;:0},&quot;streetViewControlOptions&quot;:{&quot;position&quot;:22},&quot;fullscreenControlOptions&quot;:{&quot;position&quot;:20},&quot;@provider&quot;:&quot;google&quot;}"
data-symfony--ux-google-map--map-markers-value="[]"
data-symfony--ux-google-map--map-polygons-value="[]"
data-symfony--ux-google-map--map-polylines-value="[]"
class="map"
></div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- This HTML has been prettified for testing purposes, and may not represent the actual HTML output.
Run "php vendor/bin/phpunit -d --update-snapshots" to update the snapshot. -->
<div
data-controller="symfony--ux-google-map--map"
data-symfony--ux-google-map--map-provider-options-value="{&quot;apiKey&quot;:&quot;my_api_key&quot;}"
data-symfony--ux-google-map--map-center-value="{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522}"
data-symfony--ux-google-map--map-zoom-value="12"
data-symfony--ux-google-map--map-fit-bounds-to-markers-value="false"
data-symfony--ux-google-map--map-options-value="{&quot;mapId&quot;:&quot;CustomMapId&quot;,&quot;gestureHandling&quot;:&quot;auto&quot;,&quot;backgroundColor&quot;:null,&quot;disableDoubleClickZoom&quot;:false,&quot;zoomControlOptions&quot;:{&quot;position&quot;:22},&quot;mapTypeControlOptions&quot;:{&quot;mapTypeIds&quot;:[],&quot;position&quot;:14,&quot;style&quot;:0},&quot;streetViewControlOptions&quot;:{&quot;position&quot;:22},&quot;fullscreenControlOptions&quot;:{&quot;position&quot;:20},&quot;@provider&quot;:&quot;google&quot;}"
data-symfony--ux-google-map--map-markers-value="[]"
data-symfony--ux-google-map--map-polygons-value="[]"
data-symfony--ux-google-map--map-polylines-value="[]"
></div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- This HTML has been prettified for testing purposes, and may not represent the actual HTML output.
Run "php vendor/bin/phpunit -d --update-snapshots" to update the snapshot. -->
<div
data-controller="symfony--ux-google-map--map"
data-symfony--ux-google-map--map-provider-options-value="{&quot;apiKey&quot;:&quot;my_api_key&quot;}"
data-symfony--ux-google-map--map-center-value="{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522}"
data-symfony--ux-google-map--map-zoom-value="12"
data-symfony--ux-google-map--map-fit-bounds-to-markers-value="false"
data-symfony--ux-google-map--map-options-value="{&quot;mapId&quot;:&quot;DefaultMapId&quot;,&quot;gestureHandling&quot;:&quot;auto&quot;,&quot;backgroundColor&quot;:null,&quot;disableDoubleClickZoom&quot;:false,&quot;zoomControlOptions&quot;:{&quot;position&quot;:22},&quot;mapTypeControlOptions&quot;:{&quot;mapTypeIds&quot;:[],&quot;position&quot;:14,&quot;style&quot;:0},&quot;streetViewControlOptions&quot;:{&quot;position&quot;:22},&quot;fullscreenControlOptions&quot;:{&quot;position&quot;:20},&quot;@provider&quot;:&quot;google&quot;}"
data-symfony--ux-google-map--map-markers-value="[]"
data-symfony--ux-google-map--map-polygons-value="[]"
data-symfony--ux-google-map--map-polylines-value="[]"
></div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- This HTML has been prettified for testing purposes, and may not represent the actual HTML output.
Run "php vendor/bin/phpunit -d --update-snapshots" to update the snapshot. -->
<div
data-controller="symfony--ux-google-map--map"
data-symfony--ux-google-map--map-provider-options-value="{&quot;apiKey&quot;:&quot;my_api_key&quot;}"
data-symfony--ux-google-map--map-center-value="{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522}"
data-symfony--ux-google-map--map-zoom-value="12"
data-symfony--ux-google-map--map-fit-bounds-to-markers-value="false"
data-symfony--ux-google-map--map-options-value="{&quot;mapId&quot;:&quot;DefaultMapId&quot;,&quot;gestureHandling&quot;:&quot;auto&quot;,&quot;backgroundColor&quot;:null,&quot;disableDoubleClickZoom&quot;:false,&quot;zoomControlOptions&quot;:{&quot;position&quot;:22},&quot;mapTypeControlOptions&quot;:{&quot;mapTypeIds&quot;:[],&quot;position&quot;:14,&quot;style&quot;:0},&quot;streetViewControlOptions&quot;:{&quot;position&quot;:22},&quot;fullscreenControlOptions&quot;:{&quot;position&quot;:20},&quot;@provider&quot;:&quot;google&quot;}"
data-symfony--ux-google-map--map-markers-value="[]"
data-symfony--ux-google-map--map-polygons-value="[]"
data-symfony--ux-google-map--map-polylines-value="[]"
></div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- This HTML has been prettified for testing purposes, and may not represent the actual HTML output.
Run "php vendor/bin/phpunit -d --update-snapshots" to update the snapshot. -->
<div
data-controller="symfony--ux-google-map--map"
data-symfony--ux-google-map--map-provider-options-value="{&quot;id&quot;:&quot;gmap&quot;,&quot;language&quot;:&quot;fr&quot;,&quot;region&quot;:&quot;FR&quot;,&quot;nonce&quot;:&quot;abcd&quot;,&quot;retries&quot;:10,&quot;url&quot;:&quot;https:\/\/maps.googleapis.com\/maps\/api\/js&quot;,&quot;version&quot;:&quot;quarterly&quot;,&quot;apiKey&quot;:&quot;api_key&quot;}"
data-symfony--ux-google-map--map-center-value="{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522}"
data-symfony--ux-google-map--map-zoom-value="12"
data-symfony--ux-google-map--map-fit-bounds-to-markers-value="false"
data-symfony--ux-google-map--map-options-value="{&quot;mapId&quot;:null,&quot;gestureHandling&quot;:&quot;auto&quot;,&quot;backgroundColor&quot;:null,&quot;disableDoubleClickZoom&quot;:false,&quot;zoomControlOptions&quot;:{&quot;position&quot;:22},&quot;mapTypeControlOptions&quot;:{&quot;mapTypeIds&quot;:[],&quot;position&quot;:14,&quot;style&quot;:0},&quot;streetViewControlOptions&quot;:{&quot;position&quot;:22},&quot;fullscreenControlOptions&quot;:{&quot;position&quot;:20},&quot;@provider&quot;:&quot;google&quot;}"
data-symfony--ux-google-map--map-markers-value="[]"
data-symfony--ux-google-map--map-polygons-value="[]"
data-symfony--ux-google-map--map-polylines-value="[]"
></div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- This HTML has been prettified for testing purposes, and may not represent the actual HTML output.
Run "php vendor/bin/phpunit -d --update-snapshots" to update the snapshot. -->
<div
data-controller="symfony--ux-google-map--map"
data-symfony--ux-google-map--map-provider-options-value="{&quot;apiKey&quot;:&quot;api_key&quot;}"
data-symfony--ux-google-map--map-center-value="{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522}"
data-symfony--ux-google-map--map-zoom-value="12"
data-symfony--ux-google-map--map-fit-bounds-to-markers-value="false"
data-symfony--ux-google-map--map-options-value="{&quot;mapId&quot;:null,&quot;gestureHandling&quot;:&quot;auto&quot;,&quot;backgroundColor&quot;:null,&quot;disableDoubleClickZoom&quot;:false,&quot;zoomControlOptions&quot;:{&quot;position&quot;:22},&quot;mapTypeControlOptions&quot;:{&quot;mapTypeIds&quot;:[],&quot;position&quot;:14,&quot;style&quot;:0},&quot;streetViewControlOptions&quot;:{&quot;position&quot;:22},&quot;fullscreenControlOptions&quot;:{&quot;position&quot;:20},&quot;@provider&quot;:&quot;google&quot;}"
data-symfony--ux-google-map--map-markers-value="[{&quot;position&quot;:{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522},&quot;title&quot;:&quot;Paris&quot;,&quot;infoWindow&quot;:null,&quot;icon&quot;:null,&quot;extra&quot;:[],&quot;id&quot;:&quot;marker1&quot;,&quot;@id&quot;:&quot;872feba9ebf3905d&quot;},{&quot;position&quot;:{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522},&quot;title&quot;:&quot;Lyon&quot;,&quot;infoWindow&quot;:{&quot;headerContent&quot;:null,&quot;content&quot;:&quot;Lyon&quot;,&quot;position&quot;:null,&quot;opened&quot;:false,&quot;autoClose&quot;:true,&quot;extra&quot;:[]},&quot;icon&quot;:null,&quot;extra&quot;:[],&quot;id&quot;:&quot;marker2&quot;,&quot;@id&quot;:&quot;6028bf5e41f644ab&quot;}]"
data-symfony--ux-google-map--map-polygons-value="[]"
data-symfony--ux-google-map--map-polylines-value="[]"
></div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- This HTML has been prettified for testing purposes, and may not represent the actual HTML output.
Run "php vendor/bin/phpunit -d --update-snapshots" to update the snapshot. -->
<div
data-controller="symfony--ux-google-map--map"
data-symfony--ux-google-map--map-provider-options-value="{&quot;apiKey&quot;:&quot;api_key&quot;}"
data-symfony--ux-google-map--map-center-value="{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522}"
data-symfony--ux-google-map--map-zoom-value="12"
data-symfony--ux-google-map--map-fit-bounds-to-markers-value="false"
data-symfony--ux-google-map--map-options-value="{&quot;mapId&quot;:null,&quot;gestureHandling&quot;:&quot;auto&quot;,&quot;backgroundColor&quot;:null,&quot;disableDoubleClickZoom&quot;:false,&quot;zoomControlOptions&quot;:{&quot;position&quot;:22},&quot;mapTypeControlOptions&quot;:{&quot;mapTypeIds&quot;:[],&quot;position&quot;:14,&quot;style&quot;:0},&quot;streetViewControlOptions&quot;:{&quot;position&quot;:22},&quot;fullscreenControlOptions&quot;:{&quot;position&quot;:20},&quot;@provider&quot;:&quot;google&quot;}"
data-symfony--ux-google-map--map-markers-value="[{&quot;position&quot;:{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522},&quot;title&quot;:&quot;Paris&quot;,&quot;infoWindow&quot;:null,&quot;icon&quot;:null,&quot;extra&quot;:[],&quot;id&quot;:&quot;marker1&quot;,&quot;@id&quot;:&quot;872feba9ebf3905d&quot;},{&quot;position&quot;:{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522},&quot;title&quot;:&quot;Lyon&quot;,&quot;infoWindow&quot;:{&quot;headerContent&quot;:null,&quot;content&quot;:&quot;Lyon&quot;,&quot;position&quot;:null,&quot;opened&quot;:false,&quot;autoClose&quot;:true,&quot;extra&quot;:[]},&quot;icon&quot;:null,&quot;extra&quot;:[],&quot;id&quot;:null,&quot;@id&quot;:&quot;bce206d73dc5c164&quot;}]"
data-symfony--ux-google-map--map-polygons-value="[]"
data-symfony--ux-google-map--map-polylines-value="[]"
></div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- This HTML has been prettified for testing purposes, and may not represent the actual HTML output.
Run "php vendor/bin/phpunit -d --update-snapshots" to update the snapshot. -->
<div
data-controller="symfony--ux-google-map--map"
data-symfony--ux-google-map--map-provider-options-value="{&quot;apiKey&quot;:&quot;api_key&quot;}"
data-symfony--ux-google-map--map-center-value="{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522}"
data-symfony--ux-google-map--map-zoom-value="12"
data-symfony--ux-google-map--map-fit-bounds-to-markers-value="false"
data-symfony--ux-google-map--map-options-value="{&quot;mapId&quot;:null,&quot;gestureHandling&quot;:&quot;auto&quot;,&quot;backgroundColor&quot;:null,&quot;disableDoubleClickZoom&quot;:false,&quot;zoomControlOptions&quot;:{&quot;position&quot;:22},&quot;mapTypeControlOptions&quot;:{&quot;mapTypeIds&quot;:[],&quot;position&quot;:14,&quot;style&quot;:0},&quot;streetViewControlOptions&quot;:{&quot;position&quot;:22},&quot;fullscreenControlOptions&quot;:{&quot;position&quot;:20},&quot;@provider&quot;:&quot;google&quot;}"
data-symfony--ux-google-map--map-markers-value="[]"
data-symfony--ux-google-map--map-polygons-value="[{&quot;points&quot;:[{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522},{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522},{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522}],&quot;title&quot;:null,&quot;infoWindow&quot;:null,&quot;extra&quot;:[],&quot;id&quot;:null,&quot;@id&quot;:&quot;7cdd432ea54d0ce9&quot;},{&quot;points&quot;:[{&quot;lat&quot;:1.1,&quot;lng&quot;:2.2},{&quot;lat&quot;:3.3,&quot;lng&quot;:4.4},{&quot;lat&quot;:5.5,&quot;lng&quot;:6.6}],&quot;title&quot;:null,&quot;infoWindow&quot;:{&quot;headerContent&quot;:null,&quot;content&quot;:&quot;Polygon&quot;,&quot;position&quot;:null,&quot;opened&quot;:false,&quot;autoClose&quot;:true,&quot;extra&quot;:[]},&quot;extra&quot;:[],&quot;id&quot;:null,&quot;@id&quot;:&quot;9074e0a9ead08c1e&quot;}]"
data-symfony--ux-google-map--map-polylines-value="[]"
></div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- This HTML has been prettified for testing purposes, and may not represent the actual HTML output.
Run "php vendor/bin/phpunit -d --update-snapshots" to update the snapshot. -->
<div
data-controller="symfony--ux-google-map--map"
data-symfony--ux-google-map--map-provider-options-value="{&quot;apiKey&quot;:&quot;api_key&quot;}"
data-symfony--ux-google-map--map-center-value="{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522}"
data-symfony--ux-google-map--map-zoom-value="12"
data-symfony--ux-google-map--map-fit-bounds-to-markers-value="false"
data-symfony--ux-google-map--map-options-value="{&quot;mapId&quot;:null,&quot;gestureHandling&quot;:&quot;auto&quot;,&quot;backgroundColor&quot;:null,&quot;disableDoubleClickZoom&quot;:false,&quot;zoomControlOptions&quot;:{&quot;position&quot;:22},&quot;mapTypeControlOptions&quot;:{&quot;mapTypeIds&quot;:[],&quot;position&quot;:14,&quot;style&quot;:0},&quot;streetViewControlOptions&quot;:{&quot;position&quot;:22},&quot;fullscreenControlOptions&quot;:{&quot;position&quot;:20},&quot;@provider&quot;:&quot;google&quot;}"
data-symfony--ux-google-map--map-markers-value="[]"
data-symfony--ux-google-map--map-polygons-value="[]"
data-symfony--ux-google-map--map-polylines-value="[{&quot;points&quot;:[{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522},{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522},{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522}],&quot;title&quot;:null,&quot;infoWindow&quot;:null,&quot;extra&quot;:[],&quot;id&quot;:null,&quot;@id&quot;:&quot;7cdd432ea54d0ce9&quot;},{&quot;points&quot;:[{&quot;lat&quot;:1.1,&quot;lng&quot;:2.2},{&quot;lat&quot;:3.3,&quot;lng&quot;:4.4},{&quot;lat&quot;:5.5,&quot;lng&quot;:6.6}],&quot;title&quot;:null,&quot;infoWindow&quot;:{&quot;headerContent&quot;:null,&quot;content&quot;:&quot;Polygon&quot;,&quot;position&quot;:null,&quot;opened&quot;:false,&quot;autoClose&quot;:true,&quot;extra&quot;:[]},&quot;extra&quot;:[],&quot;id&quot;:null,&quot;@id&quot;:&quot;9074e0a9ead08c1e&quot;}]"
></div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- This HTML has been prettified for testing purposes, and may not represent the actual HTML output.
Run "php vendor/bin/phpunit -d --update-snapshots" to update the snapshot. -->
<div
data-controller="symfony--ux-google-map--map"
data-symfony--ux-google-map--map-provider-options-value="{&quot;apiKey&quot;:&quot;api_key&quot;}"
data-symfony--ux-google-map--map-center-value="{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522}"
data-symfony--ux-google-map--map-zoom-value="12"
data-symfony--ux-google-map--map-fit-bounds-to-markers-value="false"
data-symfony--ux-google-map--map-options-value="{&quot;mapId&quot;:null,&quot;gestureHandling&quot;:&quot;auto&quot;,&quot;backgroundColor&quot;:null,&quot;disableDoubleClickZoom&quot;:false,&quot;@provider&quot;:&quot;google&quot;}"
data-symfony--ux-google-map--map-markers-value="[]"
data-symfony--ux-google-map--map-polygons-value="[]"
data-symfony--ux-google-map--map-polylines-value="[]"
></div>
8 changes: 6 additions & 2 deletions src/Map/src/Bridge/Leaflet/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
# CHANGELOG

## 2.25

- Downgrade PHP requirement from 8.3 to 8.1

## 2.20

### BC Breaks

- Renamed importmap entry `@symfony/ux-leaflet-map/map-controller` to `@symfony/ux-leaflet-map`,
you will need to update your importmap.
- Renamed importmap entry `@symfony/ux-leaflet-map/map-controller` to `@symfony/ux-leaflet-map`,
you will need to update your importmap.

## 2.19

2 changes: 2 additions & 0 deletions src/Map/src/Bridge/Leaflet/assets/README.md
Original file line number Diff line number Diff line change
@@ -14,6 +14,8 @@ composer require symfony/ux-leaflet-map:2.23.0
npm add @symfony/ux-leaflet-map@2.23.0
```

**Tip:** Your `package.json` file will be automatically modified by [Flex](https://github.com/symfony/flex) when installing or upgrading a PHP package. To prevent this behavior, ensure to **use at least Flex 1.22.0 or 2.5.0**, and run `composer config extra.symfony.flex.synchronize_package_json false`.

## Resources

- [Documentation](https://github.com/symfony/ux/tree/2.x/src/Map/src/Bridge/Google)
2 changes: 1 addition & 1 deletion src/Map/src/Bridge/Leaflet/assets/package.json
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
"name": "@symfony/ux-leaflet-map",
"description": "Leaflet bridge for Symfony UX Map, integrate interactive maps in your Symfony applications",
"license": "MIT",
"version": "2.23.0",
"version": "2.24.0",
"keywords": [
"symfony-ux",
"leaflet",
8 changes: 5 additions & 3 deletions src/Map/src/Bridge/Leaflet/composer.json
Original file line number Diff line number Diff line change
@@ -16,13 +16,15 @@
}
],
"require": {
"php": ">=8.3",
"php": ">=8.1",
"symfony/stimulus-bundle": "^2.18.1",
"symfony/ux-map": "^2.19"
},
"require-dev": {
"symfony/phpunit-bridge": "^6.4|^7.0",
"symfony/ux-icons": "^2.18"
"symfony/phpunit-bridge": "^7.2",
"symfony/ux-icons": "^2.18",
"spatie/phpunit-snapshot-assertions": "^4.2.17",
"phpunit/phpunit": "^9.6.22"
},
"autoload": {
"psr-4": { "Symfony\\UX\\Map\\Bridge\\Leaflet\\": "src/" },
2 changes: 1 addition & 1 deletion src/Map/src/Bridge/Leaflet/phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@
<directory suffix=".php">./src</directory>
</include>
</coverage>

<php>
<ini name="error_reporting" value="-1"/>
<server name="SYMFONY_DEPRECATIONS_HELPER" value="max[self]=0&amp;max[direct]=0"/>
8 changes: 4 additions & 4 deletions src/Map/src/Bridge/Leaflet/src/Option/TileLayer.php
Original file line number Diff line number Diff line change
@@ -18,15 +18,15 @@
*
* @author Hugo Alliaume <hugo@alliau.me>
*/
final readonly class TileLayer
final class TileLayer
{
/**
* @param array<mixed> $options
*/
public function __construct(
private string $url,
private string $attribution,
private array $options = [],
private readonly string $url,
private readonly string $attribution,
private readonly array $options = [],
) {
}

Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@
*
* @internal
*/
final readonly class LeafletRenderer extends AbstractRenderer
final class LeafletRenderer extends AbstractRenderer
{
protected function getName(): string
{
10 changes: 1 addition & 9 deletions src/Map/src/Bridge/Leaflet/tests/LeafletRendererTest.php
Original file line number Diff line number Diff line change
@@ -26,7 +26,7 @@

class LeafletRendererTest extends RendererTestCase
{
public function provideTestRenderMap(): iterable
public static function provideTestRenderMap(): iterable
{
$map = (new Map())
->center(new Point(48.8566, 2.3522))
@@ -37,20 +37,17 @@ public function provideTestRenderMap(): iterable
$marker3 = new Marker(position: new Point(45.8566, 2.3522), title: 'Dijon', id: 'marker3');

yield 'simple map' => [
'expected_render' => '<div data-controller="symfony--ux-leaflet-map--map" data-symfony--ux-leaflet-map--map-provider-options-value="{}" data-symfony--ux-leaflet-map--map-center-value="{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522}" data-symfony--ux-leaflet-map--map-zoom-value="12" data-symfony--ux-leaflet-map--map-fit-bounds-to-markers-value="false" data-symfony--ux-leaflet-map--map-options-value="{&quot;tileLayer&quot;:{&quot;url&quot;:&quot;https:\/\/tile.openstreetmap.org\/{z}\/{x}\/{y}.png&quot;,&quot;attribution&quot;:&quot;\u00a9 &lt;a href=\&quot;https:\/\/www.openstreetmap.org\/copyright\&quot;&gt;OpenStreetMap&lt;\/a&gt;&quot;,&quot;options&quot;:[]},&quot;@provider&quot;:&quot;leaflet&quot;}" data-symfony--ux-leaflet-map--map-markers-value="[]" data-symfony--ux-leaflet-map--map-polygons-value="[]" data-symfony--ux-leaflet-map--map-polylines-value="[]"></div>',
'renderer' => new LeafletRenderer(new StimulusHelper(null), new UxIconRenderer(null)),
'map' => (clone $map),
];

yield 'with custom attributes' => [
'expected_render' => '<div data-controller="my-custom-controller symfony--ux-leaflet-map--map" data-symfony--ux-leaflet-map--map-provider-options-value="{}" data-symfony--ux-leaflet-map--map-center-value="{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522}" data-symfony--ux-leaflet-map--map-zoom-value="12" data-symfony--ux-leaflet-map--map-fit-bounds-to-markers-value="false" data-symfony--ux-leaflet-map--map-options-value="{&quot;tileLayer&quot;:{&quot;url&quot;:&quot;https:\/\/tile.openstreetmap.org\/{z}\/{x}\/{y}.png&quot;,&quot;attribution&quot;:&quot;\u00a9 &lt;a href=\&quot;https:\/\/www.openstreetmap.org\/copyright\&quot;&gt;OpenStreetMap&lt;\/a&gt;&quot;,&quot;options&quot;:[]},&quot;@provider&quot;:&quot;leaflet&quot;}" data-symfony--ux-leaflet-map--map-markers-value="[]" data-symfony--ux-leaflet-map--map-polygons-value="[]" data-symfony--ux-leaflet-map--map-polylines-value="[]" class="map"></div>',
'renderer' => new LeafletRenderer(new StimulusHelper(null), new UxIconRenderer(null)),
'map' => (clone $map),
'attributes' => ['data-controller' => 'my-custom-controller', 'class' => 'map'],
];

yield 'with markers and infoWindows' => [
'expected_render' => '<div data-controller="symfony--ux-leaflet-map--map" data-symfony--ux-leaflet-map--map-provider-options-value="{}" data-symfony--ux-leaflet-map--map-center-value="{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522}" data-symfony--ux-leaflet-map--map-zoom-value="12" data-symfony--ux-leaflet-map--map-fit-bounds-to-markers-value="false" data-symfony--ux-leaflet-map--map-options-value="{&quot;tileLayer&quot;:{&quot;url&quot;:&quot;https:\/\/tile.openstreetmap.org\/{z}\/{x}\/{y}.png&quot;,&quot;attribution&quot;:&quot;\u00a9 &lt;a href=\&quot;https:\/\/www.openstreetmap.org\/copyright\&quot;&gt;OpenStreetMap&lt;\/a&gt;&quot;,&quot;options&quot;:[]},&quot;@provider&quot;:&quot;leaflet&quot;}" data-symfony--ux-leaflet-map--map-markers-value="[{&quot;position&quot;:{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522},&quot;title&quot;:&quot;Paris&quot;,&quot;infoWindow&quot;:null,&quot;icon&quot;:null,&quot;extra&quot;:[],&quot;id&quot;:&quot;marker1&quot;,&quot;@id&quot;:&quot;872feba9ebf3905d&quot;},{&quot;position&quot;:{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522},&quot;title&quot;:&quot;Lyon&quot;,&quot;infoWindow&quot;:{&quot;headerContent&quot;:null,&quot;content&quot;:&quot;Lyon&quot;,&quot;position&quot;:null,&quot;opened&quot;:false,&quot;autoClose&quot;:true,&quot;extra&quot;:[]},&quot;icon&quot;:null,&quot;extra&quot;:[],&quot;id&quot;:null,&quot;@id&quot;:&quot;bce206d73dc5c164&quot;}]" data-symfony--ux-leaflet-map--map-polygons-value="[]" data-symfony--ux-leaflet-map--map-polylines-value="[]"></div>',
'renderer' => new LeafletRenderer(new StimulusHelper(null), new UxIconRenderer(null)),
'map' => (new Map())
->center(new Point(48.8566, 2.3522))
@@ -60,7 +57,6 @@ public function provideTestRenderMap(): iterable
];

yield 'with all markers removed' => [
'expected_render' => '<div data-controller="symfony--ux-leaflet-map--map" data-symfony--ux-leaflet-map--map-provider-options-value="{}" data-symfony--ux-leaflet-map--map-center-value="{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522}" data-symfony--ux-leaflet-map--map-zoom-value="12" data-symfony--ux-leaflet-map--map-fit-bounds-to-markers-value="false" data-symfony--ux-leaflet-map--map-options-value="{&quot;tileLayer&quot;:{&quot;url&quot;:&quot;https:\/\/tile.openstreetmap.org\/{z}\/{x}\/{y}.png&quot;,&quot;attribution&quot;:&quot;\u00a9 &lt;a href=\&quot;https:\/\/www.openstreetmap.org\/copyright\&quot;&gt;OpenStreetMap&lt;\/a&gt;&quot;,&quot;options&quot;:[]},&quot;@provider&quot;:&quot;leaflet&quot;}" data-symfony--ux-leaflet-map--map-markers-value="[]" data-symfony--ux-leaflet-map--map-polygons-value="[]" data-symfony--ux-leaflet-map--map-polylines-value="[]"></div>',
'renderer' => new LeafletRenderer(new StimulusHelper(null), new UxIconRenderer(null)),
'map' => (new Map())
->center(new Point(48.8566, 2.3522))
@@ -72,7 +68,6 @@ public function provideTestRenderMap(): iterable
];

yield 'with marker remove and new ones added' => [
'expected_render' => '<div data-controller="symfony--ux-leaflet-map--map" data-symfony--ux-leaflet-map--map-provider-options-value="{}" data-symfony--ux-leaflet-map--map-center-value="{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522}" data-symfony--ux-leaflet-map--map-zoom-value="12" data-symfony--ux-leaflet-map--map-fit-bounds-to-markers-value="false" data-symfony--ux-leaflet-map--map-options-value="{&quot;tileLayer&quot;:{&quot;url&quot;:&quot;https:\/\/tile.openstreetmap.org\/{z}\/{x}\/{y}.png&quot;,&quot;attribution&quot;:&quot;\u00a9 &lt;a href=\&quot;https:\/\/www.openstreetmap.org\/copyright\&quot;&gt;OpenStreetMap&lt;\/a&gt;&quot;,&quot;options&quot;:[]},&quot;@provider&quot;:&quot;leaflet&quot;}" data-symfony--ux-leaflet-map--map-markers-value="[{&quot;position&quot;:{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522},&quot;title&quot;:&quot;Paris&quot;,&quot;infoWindow&quot;:null,&quot;icon&quot;:null,&quot;extra&quot;:[],&quot;id&quot;:&quot;marker1&quot;,&quot;@id&quot;:&quot;872feba9ebf3905d&quot;},{&quot;position&quot;:{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522},&quot;title&quot;:&quot;Lyon&quot;,&quot;infoWindow&quot;:{&quot;headerContent&quot;:null,&quot;content&quot;:&quot;Lyon&quot;,&quot;position&quot;:null,&quot;opened&quot;:false,&quot;autoClose&quot;:true,&quot;extra&quot;:[]},&quot;icon&quot;:null,&quot;extra&quot;:[],&quot;id&quot;:&quot;marker2&quot;,&quot;@id&quot;:&quot;6028bf5e41f644ab&quot;}]" data-symfony--ux-leaflet-map--map-polygons-value="[]" data-symfony--ux-leaflet-map--map-polylines-value="[]"></div>',
'renderer' => new LeafletRenderer(new StimulusHelper(null), new UxIconRenderer(null)),
'map' => (new Map())
->center(new Point(48.8566, 2.3522))
@@ -84,7 +79,6 @@ public function provideTestRenderMap(): iterable
];

yield 'with polygons and infoWindows' => [
'expected_render' => '<div data-controller="symfony--ux-leaflet-map--map" data-symfony--ux-leaflet-map--map-provider-options-value="{}" data-symfony--ux-leaflet-map--map-center-value="{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522}" data-symfony--ux-leaflet-map--map-zoom-value="12" data-symfony--ux-leaflet-map--map-fit-bounds-to-markers-value="false" data-symfony--ux-leaflet-map--map-options-value="{&quot;tileLayer&quot;:{&quot;url&quot;:&quot;https:\/\/tile.openstreetmap.org\/{z}\/{x}\/{y}.png&quot;,&quot;attribution&quot;:&quot;\u00a9 &lt;a href=\&quot;https:\/\/www.openstreetmap.org\/copyright\&quot;&gt;OpenStreetMap&lt;\/a&gt;&quot;,&quot;options&quot;:[]},&quot;@provider&quot;:&quot;leaflet&quot;}" data-symfony--ux-leaflet-map--map-markers-value="[]" data-symfony--ux-leaflet-map--map-polygons-value="[{&quot;points&quot;:[{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522},{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522},{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522}],&quot;title&quot;:null,&quot;infoWindow&quot;:null,&quot;extra&quot;:[],&quot;id&quot;:&quot;polygon1&quot;,&quot;@id&quot;:&quot;35bfa920335b849d&quot;},{&quot;points&quot;:[{&quot;lat&quot;:1.1,&quot;lng&quot;:2.2},{&quot;lat&quot;:3.3,&quot;lng&quot;:4.4},{&quot;lat&quot;:5.5,&quot;lng&quot;:6.6}],&quot;title&quot;:null,&quot;infoWindow&quot;:{&quot;headerContent&quot;:null,&quot;content&quot;:&quot;Polygon&quot;,&quot;position&quot;:null,&quot;opened&quot;:false,&quot;autoClose&quot;:true,&quot;extra&quot;:[]},&quot;extra&quot;:[],&quot;id&quot;:&quot;polygon2&quot;,&quot;@id&quot;:&quot;7be1fe9f10489d73&quot;}]" data-symfony--ux-leaflet-map--map-polylines-value="[]"></div>',
'renderer' => new LeafletRenderer(new StimulusHelper(null), new UxIconRenderer(null)),
'map' => (new Map())
->center(new Point(48.8566, 2.3522))
@@ -94,7 +88,6 @@ public function provideTestRenderMap(): iterable
];

yield 'with polylines and infoWindows' => [
'expected_render' => '<div data-controller="symfony--ux-leaflet-map--map" data-symfony--ux-leaflet-map--map-provider-options-value="{}" data-symfony--ux-leaflet-map--map-center-value="{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522}" data-symfony--ux-leaflet-map--map-zoom-value="12" data-symfony--ux-leaflet-map--map-fit-bounds-to-markers-value="false" data-symfony--ux-leaflet-map--map-options-value="{&quot;tileLayer&quot;:{&quot;url&quot;:&quot;https:\/\/tile.openstreetmap.org\/{z}\/{x}\/{y}.png&quot;,&quot;attribution&quot;:&quot;\u00a9 &lt;a href=\&quot;https:\/\/www.openstreetmap.org\/copyright\&quot;&gt;OpenStreetMap&lt;\/a&gt;&quot;,&quot;options&quot;:[]},&quot;@provider&quot;:&quot;leaflet&quot;}" data-symfony--ux-leaflet-map--map-markers-value="[]" data-symfony--ux-leaflet-map--map-polygons-value="[]" data-symfony--ux-leaflet-map--map-polylines-value="[{&quot;points&quot;:[{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522},{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522},{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522}],&quot;title&quot;:null,&quot;infoWindow&quot;:null,&quot;extra&quot;:[],&quot;id&quot;:&quot;polyline1&quot;,&quot;@id&quot;:&quot;823f6ee5acdb5db3&quot;},{&quot;points&quot;:[{&quot;lat&quot;:1.1,&quot;lng&quot;:2.2},{&quot;lat&quot;:3.3,&quot;lng&quot;:4.4},{&quot;lat&quot;:5.5,&quot;lng&quot;:6.6}],&quot;title&quot;:null,&quot;infoWindow&quot;:{&quot;headerContent&quot;:null,&quot;content&quot;:&quot;Polyline&quot;,&quot;position&quot;:null,&quot;opened&quot;:false,&quot;autoClose&quot;:true,&quot;extra&quot;:[]},&quot;extra&quot;:[],&quot;id&quot;:&quot;polyline2&quot;,&quot;@id&quot;:&quot;77fb0e390b5e91f1&quot;}]"></div>',
'renderer' => new LeafletRenderer(new StimulusHelper(null), new UxIconRenderer(null)),
'map' => (new Map())
->center(new Point(48.8566, 2.3522))
@@ -104,7 +97,6 @@ public function provideTestRenderMap(): iterable
];

yield 'markers with icons' => [
'expected_render' => '<div data-controller="symfony--ux-leaflet-map--map" data-symfony--ux-leaflet-map--map-provider-options-value="{}" data-symfony--ux-leaflet-map--map-center-value="{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522}" data-symfony--ux-leaflet-map--map-zoom-value="12" data-symfony--ux-leaflet-map--map-fit-bounds-to-markers-value="false" data-symfony--ux-leaflet-map--map-options-value="{&quot;tileLayer&quot;:{&quot;url&quot;:&quot;https:\/\/tile.openstreetmap.org\/{z}\/{x}\/{y}.png&quot;,&quot;attribution&quot;:&quot;\u00a9 &lt;a href=\&quot;https:\/\/www.openstreetmap.org\/copyright\&quot;&gt;OpenStreetMap&lt;\/a&gt;&quot;,&quot;options&quot;:[]},&quot;@provider&quot;:&quot;leaflet&quot;}" data-symfony--ux-leaflet-map--map-markers-value="[{&quot;position&quot;:{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522},&quot;title&quot;:&quot;Paris&quot;,&quot;infoWindow&quot;:null,&quot;icon&quot;:{&quot;type&quot;:&quot;url&quot;,&quot;width&quot;:32,&quot;height&quot;:32,&quot;url&quot;:&quot;https:\/\/cdn.jsdelivr.net\/npm\/bootstrap-icons@1.11.3\/icons\/geo-alt.svg&quot;},&quot;extra&quot;:[],&quot;id&quot;:null,&quot;@id&quot;:&quot;217fa57668ad8e64&quot;},{&quot;position&quot;:{&quot;lat&quot;:45.764,&quot;lng&quot;:4.8357},&quot;title&quot;:&quot;Lyon&quot;,&quot;infoWindow&quot;:null,&quot;icon&quot;:{&quot;type&quot;:&quot;ux-icon&quot;,&quot;width&quot;:32,&quot;height&quot;:32,&quot;name&quot;:&quot;fa:map-marker&quot;,&quot;_generated_html&quot;:&quot;&lt;svg xmlns=\&quot;http:\/\/www.w3.org\/2000\/svg\&quot; width=\&quot;24\&quot; height=\&quot;24\&quot;&gt;...&lt;\/svg&gt;&quot;},&quot;extra&quot;:[],&quot;id&quot;:null,&quot;@id&quot;:&quot;255b208136900fc0&quot;},{&quot;position&quot;:{&quot;lat&quot;:45.8566,&quot;lng&quot;:2.3522},&quot;title&quot;:&quot;Dijon&quot;,&quot;infoWindow&quot;:null,&quot;icon&quot;:{&quot;type&quot;:&quot;svg&quot;,&quot;width&quot;:24,&quot;height&quot;:24,&quot;html&quot;:&quot;&lt;svg xmlns=\&quot;http:\/\/www.w3.org\/2000\/svg\&quot; width=\&quot;24\&quot; height=\&quot;24\&quot;&gt;...&lt;\/svg&gt;&quot;},&quot;extra&quot;:[],&quot;id&quot;:null,&quot;@id&quot;:&quot;1a410e92214f770c&quot;}]" data-symfony--ux-leaflet-map--map-polygons-value="[]" data-symfony--ux-leaflet-map--map-polylines-value="[]"></div>',
'renderer' => new LeafletRenderer(
new StimulusHelper(null),
new UxIconRenderer(new class implements IconRendererInterface {
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- This HTML has been prettified for testing purposes, and may not represent the actual HTML output.
Run "php vendor/bin/phpunit -d --update-snapshots" to update the snapshot. -->
<div
data-controller="symfony--ux-leaflet-map--map"
data-symfony--ux-leaflet-map--map-provider-options-value="{}"
data-symfony--ux-leaflet-map--map-center-value="{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522}"
data-symfony--ux-leaflet-map--map-zoom-value="12"
data-symfony--ux-leaflet-map--map-fit-bounds-to-markers-value="false"
data-symfony--ux-leaflet-map--map-options-value="{&quot;tileLayer&quot;:{&quot;url&quot;:&quot;https:\/\/tile.openstreetmap.org\/{z}\/{x}\/{y}.png&quot;,&quot;attribution&quot;:&quot;\u00a9 &lt;a href=\&quot;https:\/\/www.openstreetmap.org\/copyright\&quot;&gt;OpenStreetMap&lt;\/a&gt;&quot;,&quot;options&quot;:[]},&quot;@provider&quot;:&quot;leaflet&quot;}"
data-symfony--ux-leaflet-map--map-markers-value="[{&quot;position&quot;:{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522},&quot;title&quot;:&quot;Paris&quot;,&quot;infoWindow&quot;:null,&quot;icon&quot;:{&quot;type&quot;:&quot;url&quot;,&quot;width&quot;:32,&quot;height&quot;:32,&quot;url&quot;:&quot;https:\/\/cdn.jsdelivr.net\/npm\/bootstrap-icons@1.11.3\/icons\/geo-alt.svg&quot;},&quot;extra&quot;:[],&quot;id&quot;:null,&quot;@id&quot;:&quot;217fa57668ad8e64&quot;},{&quot;position&quot;:{&quot;lat&quot;:45.764,&quot;lng&quot;:4.8357},&quot;title&quot;:&quot;Lyon&quot;,&quot;infoWindow&quot;:null,&quot;icon&quot;:{&quot;type&quot;:&quot;ux-icon&quot;,&quot;width&quot;:32,&quot;height&quot;:32,&quot;name&quot;:&quot;fa:map-marker&quot;,&quot;_generated_html&quot;:&quot;&lt;svg xmlns=\&quot;http:\/\/www.w3.org\/2000\/svg\&quot; width=\&quot;24\&quot; height=\&quot;24\&quot;&gt;...&lt;\/svg&gt;&quot;},&quot;extra&quot;:[],&quot;id&quot;:null,&quot;@id&quot;:&quot;255b208136900fc0&quot;},{&quot;position&quot;:{&quot;lat&quot;:45.8566,&quot;lng&quot;:2.3522},&quot;title&quot;:&quot;Dijon&quot;,&quot;infoWindow&quot;:null,&quot;icon&quot;:{&quot;type&quot;:&quot;svg&quot;,&quot;width&quot;:24,&quot;height&quot;:24,&quot;html&quot;:&quot;&lt;svg xmlns=\&quot;http:\/\/www.w3.org\/2000\/svg\&quot; width=\&quot;24\&quot; height=\&quot;24\&quot;&gt;...&lt;\/svg&gt;&quot;},&quot;extra&quot;:[],&quot;id&quot;:null,&quot;@id&quot;:&quot;1a410e92214f770c&quot;}]"
data-symfony--ux-leaflet-map--map-polygons-value="[]"
data-symfony--ux-leaflet-map--map-polylines-value="[]"
></div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- This HTML has been prettified for testing purposes, and may not represent the actual HTML output.
Run "php vendor/bin/phpunit -d --update-snapshots" to update the snapshot. -->
<div
data-controller="symfony--ux-leaflet-map--map"
data-symfony--ux-leaflet-map--map-provider-options-value="{}"
data-symfony--ux-leaflet-map--map-center-value="{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522}"
data-symfony--ux-leaflet-map--map-zoom-value="12"
data-symfony--ux-leaflet-map--map-fit-bounds-to-markers-value="false"
data-symfony--ux-leaflet-map--map-options-value="{&quot;tileLayer&quot;:{&quot;url&quot;:&quot;https:\/\/tile.openstreetmap.org\/{z}\/{x}\/{y}.png&quot;,&quot;attribution&quot;:&quot;\u00a9 &lt;a href=\&quot;https:\/\/www.openstreetmap.org\/copyright\&quot;&gt;OpenStreetMap&lt;\/a&gt;&quot;,&quot;options&quot;:[]},&quot;@provider&quot;:&quot;leaflet&quot;}"
data-symfony--ux-leaflet-map--map-markers-value="[]"
data-symfony--ux-leaflet-map--map-polygons-value="[]"
data-symfony--ux-leaflet-map--map-polylines-value="[]"
></div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- This HTML has been prettified for testing purposes, and may not represent the actual HTML output.
Run "php vendor/bin/phpunit -d --update-snapshots" to update the snapshot. -->
<div
data-controller="symfony--ux-leaflet-map--map"
data-symfony--ux-leaflet-map--map-provider-options-value="{}"
data-symfony--ux-leaflet-map--map-center-value="{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522}"
data-symfony--ux-leaflet-map--map-zoom-value="12"
data-symfony--ux-leaflet-map--map-fit-bounds-to-markers-value="false"
data-symfony--ux-leaflet-map--map-options-value="{&quot;tileLayer&quot;:{&quot;url&quot;:&quot;https:\/\/tile.openstreetmap.org\/{z}\/{x}\/{y}.png&quot;,&quot;attribution&quot;:&quot;\u00a9 &lt;a href=\&quot;https:\/\/www.openstreetmap.org\/copyright\&quot;&gt;OpenStreetMap&lt;\/a&gt;&quot;,&quot;options&quot;:[]},&quot;@provider&quot;:&quot;leaflet&quot;}"
data-symfony--ux-leaflet-map--map-markers-value="[]"
data-symfony--ux-leaflet-map--map-polygons-value="[]"
data-symfony--ux-leaflet-map--map-polylines-value="[]"
></div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!-- This HTML has been prettified for testing purposes, and may not represent the actual HTML output.
Run "php vendor/bin/phpunit -d --update-snapshots" to update the snapshot. -->
<div
data-controller="my-custom-controller symfony--ux-leaflet-map--map"
data-symfony--ux-leaflet-map--map-provider-options-value="{}"
data-symfony--ux-leaflet-map--map-center-value="{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522}"
data-symfony--ux-leaflet-map--map-zoom-value="12"
data-symfony--ux-leaflet-map--map-fit-bounds-to-markers-value="false"
data-symfony--ux-leaflet-map--map-options-value="{&quot;tileLayer&quot;:{&quot;url&quot;:&quot;https:\/\/tile.openstreetmap.org\/{z}\/{x}\/{y}.png&quot;,&quot;attribution&quot;:&quot;\u00a9 &lt;a href=\&quot;https:\/\/www.openstreetmap.org\/copyright\&quot;&gt;OpenStreetMap&lt;\/a&gt;&quot;,&quot;options&quot;:[]},&quot;@provider&quot;:&quot;leaflet&quot;}"
data-symfony--ux-leaflet-map--map-markers-value="[]"
data-symfony--ux-leaflet-map--map-polygons-value="[]"
data-symfony--ux-leaflet-map--map-polylines-value="[]"
class="map"
></div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- This HTML has been prettified for testing purposes, and may not represent the actual HTML output.
Run "php vendor/bin/phpunit -d --update-snapshots" to update the snapshot. -->
<div
data-controller="symfony--ux-leaflet-map--map"
data-symfony--ux-leaflet-map--map-provider-options-value="{}"
data-symfony--ux-leaflet-map--map-center-value="{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522}"
data-symfony--ux-leaflet-map--map-zoom-value="12"
data-symfony--ux-leaflet-map--map-fit-bounds-to-markers-value="false"
data-symfony--ux-leaflet-map--map-options-value="{&quot;tileLayer&quot;:{&quot;url&quot;:&quot;https:\/\/tile.openstreetmap.org\/{z}\/{x}\/{y}.png&quot;,&quot;attribution&quot;:&quot;\u00a9 &lt;a href=\&quot;https:\/\/www.openstreetmap.org\/copyright\&quot;&gt;OpenStreetMap&lt;\/a&gt;&quot;,&quot;options&quot;:[]},&quot;@provider&quot;:&quot;leaflet&quot;}"
data-symfony--ux-leaflet-map--map-markers-value="[{&quot;position&quot;:{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522},&quot;title&quot;:&quot;Paris&quot;,&quot;infoWindow&quot;:null,&quot;icon&quot;:null,&quot;extra&quot;:[],&quot;id&quot;:&quot;marker1&quot;,&quot;@id&quot;:&quot;872feba9ebf3905d&quot;},{&quot;position&quot;:{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522},&quot;title&quot;:&quot;Lyon&quot;,&quot;infoWindow&quot;:{&quot;headerContent&quot;:null,&quot;content&quot;:&quot;Lyon&quot;,&quot;position&quot;:null,&quot;opened&quot;:false,&quot;autoClose&quot;:true,&quot;extra&quot;:[]},&quot;icon&quot;:null,&quot;extra&quot;:[],&quot;id&quot;:&quot;marker2&quot;,&quot;@id&quot;:&quot;6028bf5e41f644ab&quot;}]"
data-symfony--ux-leaflet-map--map-polygons-value="[]"
data-symfony--ux-leaflet-map--map-polylines-value="[]"
></div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- This HTML has been prettified for testing purposes, and may not represent the actual HTML output.
Run "php vendor/bin/phpunit -d --update-snapshots" to update the snapshot. -->
<div
data-controller="symfony--ux-leaflet-map--map"
data-symfony--ux-leaflet-map--map-provider-options-value="{}"
data-symfony--ux-leaflet-map--map-center-value="{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522}"
data-symfony--ux-leaflet-map--map-zoom-value="12"
data-symfony--ux-leaflet-map--map-fit-bounds-to-markers-value="false"
data-symfony--ux-leaflet-map--map-options-value="{&quot;tileLayer&quot;:{&quot;url&quot;:&quot;https:\/\/tile.openstreetmap.org\/{z}\/{x}\/{y}.png&quot;,&quot;attribution&quot;:&quot;\u00a9 &lt;a href=\&quot;https:\/\/www.openstreetmap.org\/copyright\&quot;&gt;OpenStreetMap&lt;\/a&gt;&quot;,&quot;options&quot;:[]},&quot;@provider&quot;:&quot;leaflet&quot;}"
data-symfony--ux-leaflet-map--map-markers-value="[{&quot;position&quot;:{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522},&quot;title&quot;:&quot;Paris&quot;,&quot;infoWindow&quot;:null,&quot;icon&quot;:null,&quot;extra&quot;:[],&quot;id&quot;:&quot;marker1&quot;,&quot;@id&quot;:&quot;872feba9ebf3905d&quot;},{&quot;position&quot;:{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522},&quot;title&quot;:&quot;Lyon&quot;,&quot;infoWindow&quot;:{&quot;headerContent&quot;:null,&quot;content&quot;:&quot;Lyon&quot;,&quot;position&quot;:null,&quot;opened&quot;:false,&quot;autoClose&quot;:true,&quot;extra&quot;:[]},&quot;icon&quot;:null,&quot;extra&quot;:[],&quot;id&quot;:null,&quot;@id&quot;:&quot;bce206d73dc5c164&quot;}]"
data-symfony--ux-leaflet-map--map-polygons-value="[]"
data-symfony--ux-leaflet-map--map-polylines-value="[]"
></div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- This HTML has been prettified for testing purposes, and may not represent the actual HTML output.
Run "php vendor/bin/phpunit -d --update-snapshots" to update the snapshot. -->
<div
data-controller="symfony--ux-leaflet-map--map"
data-symfony--ux-leaflet-map--map-provider-options-value="{}"
data-symfony--ux-leaflet-map--map-center-value="{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522}"
data-symfony--ux-leaflet-map--map-zoom-value="12"
data-symfony--ux-leaflet-map--map-fit-bounds-to-markers-value="false"
data-symfony--ux-leaflet-map--map-options-value="{&quot;tileLayer&quot;:{&quot;url&quot;:&quot;https:\/\/tile.openstreetmap.org\/{z}\/{x}\/{y}.png&quot;,&quot;attribution&quot;:&quot;\u00a9 &lt;a href=\&quot;https:\/\/www.openstreetmap.org\/copyright\&quot;&gt;OpenStreetMap&lt;\/a&gt;&quot;,&quot;options&quot;:[]},&quot;@provider&quot;:&quot;leaflet&quot;}"
data-symfony--ux-leaflet-map--map-markers-value="[]"
data-symfony--ux-leaflet-map--map-polygons-value="[{&quot;points&quot;:[{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522},{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522},{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522}],&quot;title&quot;:null,&quot;infoWindow&quot;:null,&quot;extra&quot;:[],&quot;id&quot;:&quot;polygon1&quot;,&quot;@id&quot;:&quot;35bfa920335b849d&quot;},{&quot;points&quot;:[{&quot;lat&quot;:1.1,&quot;lng&quot;:2.2},{&quot;lat&quot;:3.3,&quot;lng&quot;:4.4},{&quot;lat&quot;:5.5,&quot;lng&quot;:6.6}],&quot;title&quot;:null,&quot;infoWindow&quot;:{&quot;headerContent&quot;:null,&quot;content&quot;:&quot;Polygon&quot;,&quot;position&quot;:null,&quot;opened&quot;:false,&quot;autoClose&quot;:true,&quot;extra&quot;:[]},&quot;extra&quot;:[],&quot;id&quot;:&quot;polygon2&quot;,&quot;@id&quot;:&quot;7be1fe9f10489d73&quot;}]"
data-symfony--ux-leaflet-map--map-polylines-value="[]"
></div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- This HTML has been prettified for testing purposes, and may not represent the actual HTML output.
Run "php vendor/bin/phpunit -d --update-snapshots" to update the snapshot. -->
<div
data-controller="symfony--ux-leaflet-map--map"
data-symfony--ux-leaflet-map--map-provider-options-value="{}"
data-symfony--ux-leaflet-map--map-center-value="{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522}"
data-symfony--ux-leaflet-map--map-zoom-value="12"
data-symfony--ux-leaflet-map--map-fit-bounds-to-markers-value="false"
data-symfony--ux-leaflet-map--map-options-value="{&quot;tileLayer&quot;:{&quot;url&quot;:&quot;https:\/\/tile.openstreetmap.org\/{z}\/{x}\/{y}.png&quot;,&quot;attribution&quot;:&quot;\u00a9 &lt;a href=\&quot;https:\/\/www.openstreetmap.org\/copyright\&quot;&gt;OpenStreetMap&lt;\/a&gt;&quot;,&quot;options&quot;:[]},&quot;@provider&quot;:&quot;leaflet&quot;}"
data-symfony--ux-leaflet-map--map-markers-value="[]"
data-symfony--ux-leaflet-map--map-polygons-value="[]"
data-symfony--ux-leaflet-map--map-polylines-value="[{&quot;points&quot;:[{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522},{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522},{&quot;lat&quot;:48.8566,&quot;lng&quot;:2.3522}],&quot;title&quot;:null,&quot;infoWindow&quot;:null,&quot;extra&quot;:[],&quot;id&quot;:&quot;polyline1&quot;,&quot;@id&quot;:&quot;823f6ee5acdb5db3&quot;},{&quot;points&quot;:[{&quot;lat&quot;:1.1,&quot;lng&quot;:2.2},{&quot;lat&quot;:3.3,&quot;lng&quot;:4.4},{&quot;lat&quot;:5.5,&quot;lng&quot;:6.6}],&quot;title&quot;:null,&quot;infoWindow&quot;:{&quot;headerContent&quot;:null,&quot;content&quot;:&quot;Polyline&quot;,&quot;position&quot;:null,&quot;opened&quot;:false,&quot;autoClose&quot;:true,&quot;extra&quot;:[]},&quot;extra&quot;:[],&quot;id&quot;:&quot;polyline2&quot;,&quot;@id&quot;:&quot;77fb0e390b5e91f1&quot;}]"
></div>
6 changes: 3 additions & 3 deletions src/Map/src/Distance/DistanceCalculator.php
Original file line number Diff line number Diff line change
@@ -16,11 +16,11 @@
/**
* @author Simon André <smn.andre@gmail.com>
*/
final readonly class DistanceCalculator implements DistanceCalculatorInterface
final class DistanceCalculator implements DistanceCalculatorInterface
{
public function __construct(
private DistanceCalculatorInterface $calculator = new VincentyDistanceCalculator(),
private DistanceUnit $unit = DistanceUnit::Meter,
private readonly DistanceCalculatorInterface $calculator = new VincentyDistanceCalculator(),
private readonly DistanceUnit $unit = DistanceUnit::Meter,
) {
}

2 changes: 1 addition & 1 deletion src/Map/src/Distance/HaversineDistanceCalculator.php
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@
*
* @author Simon André <smn.andre@gmail.com>
*/
final readonly class HaversineDistanceCalculator implements DistanceCalculatorInterface
final class HaversineDistanceCalculator implements DistanceCalculatorInterface
{
/**
* @const float The Earth's radius in meters.
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@
*
* @author Simon André <smn.andre@gmail.com>
*/
final readonly class SphericalCosineDistanceCalculator implements DistanceCalculatorInterface
final class SphericalCosineDistanceCalculator implements DistanceCalculatorInterface
{
/**
* @const float The Earth's radius in meters.
2 changes: 1 addition & 1 deletion src/Map/src/Distance/VincentyDistanceCalculator.php
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@
*
* @author Simon André <smn.andre@gmail.com>
*/
final readonly class VincentyDistanceCalculator implements DistanceCalculatorInterface
final class VincentyDistanceCalculator implements DistanceCalculatorInterface
{
/**
* WS-84 ellipsoid parameters.
4 changes: 2 additions & 2 deletions src/Map/src/Icon/UxIconRenderer.php
Original file line number Diff line number Diff line change
@@ -18,10 +18,10 @@
*
* @internal
*/
readonly class UxIconRenderer
class UxIconRenderer
{
public function __construct(
private ?IconRendererInterface $renderer,
private readonly ?IconRendererInterface $renderer,
) {
}

14 changes: 7 additions & 7 deletions src/Map/src/InfoWindow.php
Original file line number Diff line number Diff line change
@@ -16,19 +16,19 @@
*
* @author Hugo Alliaume <hugo@alliau.me>
*/
final readonly class InfoWindow
final class InfoWindow
{
/**
* @param array<string, mixed> $extra Extra data, can be used by the developer to store additional information and
* use them later JavaScript side
*/
public function __construct(
private ?string $headerContent = null,
private ?string $content = null,
private ?Point $position = null,
private bool $opened = false,
private bool $autoClose = true,
private array $extra = [],
private readonly ?string $headerContent = null,
private readonly ?string $content = null,
private readonly ?Point $position = null,
private readonly bool $opened = false,
private readonly bool $autoClose = true,
private readonly array $extra = [],
) {
}

5 changes: 4 additions & 1 deletion src/Map/src/MapOptionsNormalizer.php
Original file line number Diff line number Diff line change
@@ -26,7 +26,10 @@
*/
final class MapOptionsNormalizer
{
private const string KEY_PROVIDER = '@provider';
/**
* @var string
*/
private const KEY_PROVIDER = '@provider';

/**
* @var array<string, class-string<MapOptionsInterface>>
14 changes: 7 additions & 7 deletions src/Map/src/Marker.php
Original file line number Diff line number Diff line change
@@ -20,19 +20,19 @@
*
* @author Hugo Alliaume <hugo@alliau.me>
*/
final readonly class Marker implements Element
final class Marker implements Element
{
/**
* @param array<string, mixed> $extra Extra data, can be used by the developer to store additional information and
* use them later JavaScript side
*/
public function __construct(
public Point $position,
public ?string $title = null,
public ?InfoWindow $infoWindow = null,
public array $extra = [],
public ?string $id = null,
public ?Icon $icon = null,
public readonly Point $position,
public readonly ?string $title = null,
public readonly ?InfoWindow $infoWindow = null,
public readonly array $extra = [],
public readonly ?string $id = null,
public readonly ?Icon $icon = null,
) {
}

6 changes: 3 additions & 3 deletions src/Map/src/Point.php
Original file line number Diff line number Diff line change
@@ -18,11 +18,11 @@
*
* @author Hugo Alliaume <hugo@alliau.me>
*/
final readonly class Point
final class Point
{
public function __construct(
public float $latitude,
public float $longitude,
public readonly float $latitude,
public readonly float $longitude,
) {
if ($latitude < -90 || $latitude > 90) {
throw new InvalidArgumentException(\sprintf('Latitude must be between -90 and 90 degrees, "%s" given.', $latitude));
12 changes: 6 additions & 6 deletions src/Map/src/Polygon.php
Original file line number Diff line number Diff line change
@@ -18,17 +18,17 @@
*
* @author [Pierre Svgnt]
*/
final readonly class Polygon implements Element
final class Polygon implements Element
{
/**
* @param array<string, mixed> $extra Extra data, can be used by the developer to store additional information and use them later JavaScript side
*/
public function __construct(
private array $points,
private ?string $title = null,
private ?InfoWindow $infoWindow = null,
private array $extra = [],
public ?string $id = null,
private readonly array $points,
private readonly ?string $title = null,
private readonly ?InfoWindow $infoWindow = null,
private readonly array $extra = [],
public readonly ?string $id = null,
) {
}

12 changes: 6 additions & 6 deletions src/Map/src/Polyline.php
Original file line number Diff line number Diff line change
@@ -18,17 +18,17 @@
*
* @author [Sylvain Blondeau]
*/
final readonly class Polyline implements Element
final class Polyline implements Element
{
/**
* @param array<string, mixed> $extra Extra data, can be used by the developer to store additional information and use them later JavaScript side
*/
public function __construct(
private array $points,
private ?string $title = null,
private ?InfoWindow $infoWindow = null,
private array $extra = [],
public ?string $id = null,
private readonly array $points,
private readonly ?string $title = null,
private readonly ?InfoWindow $infoWindow = null,
private readonly array $extra = [],
public readonly ?string $id = null,
) {
}

6 changes: 3 additions & 3 deletions src/Map/src/Renderer/AbstractRenderer.php
Original file line number Diff line number Diff line change
@@ -20,11 +20,11 @@
/**
* @author Hugo Alliaume <hugo@alliau.me>
*/
abstract readonly class AbstractRenderer implements RendererInterface
abstract class AbstractRenderer implements RendererInterface
{
public function __construct(
private StimulusHelper $stimulus,
private UxIconRenderer $uxIconRenderer,
private readonly StimulusHelper $stimulus,
private readonly UxIconRenderer $uxIconRenderer,
) {
}

Loading