Skip to content

Commit 03c2f59

Browse files
authored
Merge pull request #2661 from Enz000/feat/add_xmlns_attribute
[Icons] Add xmlns attribute to svg icons
2 parents 848043f + 2ce9f41 commit 03c2f59

File tree

4 files changed

+14
-5
lines changed

4 files changed

+14
-5
lines changed

src/Icons/CHANGELOG.md

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

3+
## 2.24.0
4+
5+
- 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.
6+
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).
7+
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.
8+
39
## 2.20.0
410

511
- Add `aliases` configuration option to define icon alternative names.

src/Icons/src/Iconify.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
final class Iconify
2727
{
2828
public const API_ENDPOINT = 'https://api.iconify.design';
29+
private const ATTR_XMLNS_URL = 'https://www.w3.org/2000/svg';
2930

3031
// URL must be 500 chars max (iconify limit)
3132
// -39 chars: https://api.iconify.design/XXX.json?icons=
@@ -89,6 +90,7 @@ public function fetchIcon(string $prefix, string $name): Icon
8990
}
9091

9192
return new Icon($data['icons'][$name]['body'], [
93+
'xmlns' => self::ATTR_XMLNS_URL,
9294
'viewBox' => \sprintf('0 0 %s %s', $width ?? $height, $height ?? $width),
9395
]);
9496
}
@@ -136,6 +138,7 @@ public function fetchIcons(string $prefix, array $names): array
136138
$width = $iconData['width'] ?? $data['width'] ??= $this->sets()[$prefix]['width'] ?? null;
137139

138140
$icons[$iconName] = new Icon($iconData['body'], [
141+
'xmlns' => self::ATTR_XMLNS_URL,
139142
'viewBox' => \sprintf('0 0 %d %d', $width ?? $height, $height ?? $width),
140143
]);
141144
}

src/Icons/tests/Integration/RenderIconsInTwigTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ public function testRenderIcons(): void
3333
<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>
3434
<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>
3535
<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>
36-
<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>
37-
<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>
36+
<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>
37+
<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>
3838
</ul>
3939
HTML,
4040
trim($output)
@@ -49,7 +49,7 @@ public function testRenderAliasIcons(): void
4949
$templateAlias = '<twig:ux:icon name="flowbite:x-outline" />';
5050
$outputAlias = self::getContainer()->get(Environment::class)->createTemplate($templateAlias)->render();
5151

52-
$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>';
52+
$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>';
5353
$this->assertSame($outputIcon, $expected);
5454
$this->assertSame($outputIcon, $outputAlias);
5555
}

src/Icons/tests/Unit/IconifyTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public function testFetchIcon(): void
4747
$icon = $iconify->fetchIcon('bi', 'heart');
4848

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

5353
public function testFetchIconByAlias(): void
@@ -78,7 +78,7 @@ public function testFetchIconByAlias(): void
7878
$icon = $iconify->fetchIcon('bi', 'foo');
7979

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

8484
public function testFetchIconThrowsWhenIconSetDoesNotExists(): void

0 commit comments

Comments
 (0)