Skip to content

Commit 38e685d

Browse files
committed
feature #2127 [Icons] Icon aliases (smnandre)
This PR was squashed before being merged into the 2.x branch. Discussion ---------- [Icons] Icon aliases | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | Issues | Fix # | License | MIT This PR introduce a first implementation of this feature, asked in #1767 Icon **aliases** can now be defined in the bundle configuration, to improve the DX for most used icons in a project (logo, socials, ...) ```yaml # config/packages/ux_icons.yaml ux_icons: aliases: dots: 'clarity:ellipsis-horizontal-line' ``` Now ```twig {{ ux_icon('dots') }} {# is the same as #} {{ ux_icon('clarity:ellipsis-horizontal-line') }} ``` Or... with the HTML syntax ```twig <twig:ux:icon name="dots" /> {# is the same as #} <twig:ux:icon name="clarity:ellipsis-horizontal-line" /> ``` Commits ------- 1463b5f [Icons] Icon aliases
2 parents 2a177d6 + 1463b5f commit 38e685d

File tree

6 files changed

+66
-0
lines changed

6 files changed

+66
-0
lines changed

src/Icons/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# CHANGELOG
22

3+
## 2.20.0
4+
5+
- Add `aliases` configuration option to define icon alternative names.
6+
37
## 2.19.0
48

59
- Add `ignore_not_found` option to silence error during rendering if the

src/Icons/config/services.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@
5656
->set('.ux_icons.icon_renderer', IconRenderer::class)
5757
->args([
5858
service('.ux_icons.icon_registry'),
59+
abstract_arg('default_icon_attributes'),
60+
abstract_arg('icon_aliases'),
5961
])
6062

6163
->alias('Symfony\UX\Icons\IconRendererInterface', '.ux_icons.icon_renderer')

src/Icons/doc/index.rst

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,30 @@ Now, all icons will have the ``fill`` attribute set to ``currentColor`` by defau
336336
# renders "user-profile.svg" with fill="red"
337337
{{ ux_icon('user-profile', {fill: 'red'}) }}
338338
339+
Icon Aliases
340+
~~~~~~~~~~~~
341+
342+
You can define aliases for icons in your configuration, which is helpful if
343+
you want to use a different or shorter name for an icon in your templates:
344+
345+
.. code-block:: yaml
346+
347+
# config/packages/ux_icons.yaml
348+
ux_icons:
349+
350+
aliases:
351+
dots: 'clarity:ellipsis-horizontal-line'
352+
353+
Now, you can use the ``dots`` alias in your templates:
354+
355+
.. code-block:: twig
356+
357+
{{ ux_icon('dots') }}
358+
359+
{# same as #}
360+
361+
{{ ux_icon('clarity:ellipsis-horizontal-line') }}
362+
339363
Errors
340364
------
341365

@@ -517,6 +541,11 @@ Full Configuration
517541
default_icon_attributes:
518542
# Default:
519543
fill: currentColor
544+
545+
# Icon aliases (alias => icon name).
546+
aliases:
547+
# Exemple:
548+
dots: 'clarity:ellipsis-horizontal-line'
520549
521550
# Configuration for the "on demand" icons powered by Iconify.design.
522551
iconify:

src/Icons/src/DependencyInjection/UXIconsExtension.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,14 @@ public function getConfigTreeBuilder(): TreeBuilder
4343
->info('Default attributes to add to all icons.')
4444
->defaultValue(['fill' => 'currentColor'])
4545
->end()
46+
->arrayNode('aliases')
47+
->info('Icon aliases (alias => icon name).')
48+
->example(['dots' => 'clarity:ellipsis-horizontal-line'])
49+
->normalizeKeys(false)
50+
->scalarPrototype()
51+
->cannotBeEmpty()
52+
->end()
53+
->end()
4654
->arrayNode('iconify')
4755
->info('Configuration for the "on demand" icons powered by Iconify.design.')
4856
->{interface_exists(HttpClientInterface::class) ? 'canBeDisabled' : 'canBeEnabled'}()
@@ -98,6 +106,7 @@ protected function loadInternal(array $mergedConfig, ContainerBuilder $container
98106

99107
$container->getDefinition('.ux_icons.icon_renderer')
100108
->setArgument(1, $mergedConfig['default_icon_attributes'])
109+
->setArgument(2, $mergedConfig['aliases'])
101110
;
102111

103112
$container->getDefinition('.ux_icons.twig_icon_runtime')

src/Icons/src/IconRenderer.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ final class IconRenderer implements IconRendererInterface
2121
public function __construct(
2222
private readonly IconRegistryInterface $registry,
2323
private readonly array $defaultIconAttributes = [],
24+
private readonly ?array $iconAliases = [],
2425
) {
2526
}
2627

@@ -35,6 +36,8 @@ public function __construct(
3536
*/
3637
public function renderIcon(string $name, array $attributes = []): string
3738
{
39+
$name = $this->iconAliases[$name] ?? $name;
40+
3841
$icon = $this->registry->get($name)
3942
->withAttributes($this->defaultIconAttributes)
4043
->withAttributes($attributes);

src/Icons/tests/Unit/IconRendererTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,25 @@ public static function provideAriaHiddenCases(): iterable
230230
];
231231
}
232232

233+
public function testRenderIconWithAliases(): void
234+
{
235+
$registry = $this->createRegistry([
236+
'foo' => '<path d="M0 FOO"/>',
237+
'bar' => '<path d="M0 BAR"/>',
238+
'baz' => '<path d="M0 BAZ"/>',
239+
]);
240+
$iconRenderer = new IconRenderer($registry, [], ['foo' => 'bar']);
241+
242+
$svg = $iconRenderer->renderIcon('bar');
243+
$this->assertSame('<svg aria-hidden="true"><path d="M0 BAR"/></svg>', $svg);
244+
245+
$svg = $iconRenderer->renderIcon('foo');
246+
$this->assertSame('<svg aria-hidden="true"><path d="M0 BAR"/></svg>', $svg);
247+
248+
$svg = $iconRenderer->renderIcon('baz');
249+
$this->assertSame('<svg aria-hidden="true"><path d="M0 BAZ"/></svg>', $svg);
250+
}
251+
233252
private function createRegistry(array $icons): IconRegistryInterface
234253
{
235254
$registryIcons = [];

0 commit comments

Comments
 (0)