|
<?php |
|
|
|
namespace App\Twig; |
|
|
|
// use App\Enum\Icons\BrandIcon; |
|
use App\Enum\Icons\FontAwesomeIconInterface; |
|
// use App\Enum\Icons\LightIcon; |
|
use App\Enum\Icons\RegularIcon; |
|
// use App\Enum\Icons\SolidIcon; |
|
use Symfony\Component\Asset\Packages; |
|
use Twig\Extension\AbstractExtension; |
|
use Twig\TwigFunction; |
|
use Twig\TwigTest; |
|
|
|
class FontAwesomeExtension extends AbstractExtension |
|
{ |
|
/** |
|
* Auto-generated extract of all icons we're using on the website. |
|
* |
|
* @see docs/icons.md |
|
* |
|
* @var array|string[] |
|
*/ |
|
// ##> app/icons ## |
|
public const ICONS = [ |
|
'regular-pen-to-square' => '<svg id="regular-pen-to-square" viewBox="0 0 512 512" class="%s" width="16" height="16" xmlns="http://www.w3.org/2000/svg"><path d="M454.6 45.3l12.1 12.1c12.5 12.5 12.5 32.8 0 45.3L440 129.4 382.6 72l26.7-26.7c12.5-12.5 32.8-12.5 45.3 0zM189 265.6l171-171L417.4 152l-171 171c-4.2 4.2-9.6 7.2-15.4 8.6l-65.6 15.1L180.5 281c1.3-5.8 4.3-11.2 8.6-15.4zm197.7-243L166.4 243c-8.5 8.5-14.4 19.2-17.1 30.9l-20.9 90.6c-1.2 5.4 .4 11 4.3 14.9s9.5 5.5 14.9 4.3l90.6-20.9c11.7-2.7 22.4-8.6 30.9-17.1L489.4 125.3c25-25 25-65.5 0-90.5L477.3 22.6c-25-25-65.5-25-90.5 0zM80 64C35.8 64 0 99.8 0 144V432c0 44.2 35.8 80 80 80H368c44.2 0 80-35.8 80-80V304c0-8.8-7.2-16-16-16s-16 7.2-16 16V432c0 26.5-21.5 48-48 48H80c-26.5 0-48-21.5-48-48V144c0-26.5 21.5-48 48-48H208c8.8 0 16-7.2 16-16s-7.2-16-16-16H80z"/></svg>', |
|
'regular-trash' => '<svg id="regular-trash" viewBox="0 0 448 512" class="%s" width="16" height="16" xmlns="http://www.w3.org/2000/svg"><path d="M177.7 32h92.5c5.5 0 10.6 2.8 13.6 7.5L299.1 64H148.9l15.3-24.5c2.9-4.7 8.1-7.5 13.6-7.5zM336.9 64L311 22.6C302.2 8.5 286.8 0 270.3 0H177.7C161.2 0 145.8 8.5 137 22.6L111.1 64H64.1 32 16C7.2 64 0 71.2 0 80s7.2 16 16 16H34.3L59.8 452.6C62.1 486.1 90 512 123.6 512H324.4c33.6 0 61.4-25.9 63.8-59.4L413.7 96H432c8.8 0 16-7.2 16-16s-7.2-16-16-16H416 383.9 336.9zm44.8 32L356.3 450.3C355.1 467 341.2 480 324.4 480H123.6c-16.8 0-30.7-13-31.9-29.7L66.4 96H381.6z"/></svg>', |
|
'regular-xmark' => '<svg id="regular-xmark" viewBox="0 0 384 512" class="%s" width="16" height="16" xmlns="http://www.w3.org/2000/svg"><path d="M324.5 411.1c6.2 6.2 16.4 6.2 22.6 0s6.2-16.4 0-22.6L214.6 256 347.1 123.5c6.2-6.2 6.2-16.4 0-22.6s-16.4-6.2-22.6 0L192 233.4 59.5 100.9c-6.2-6.2-16.4-6.2-22.6 0s-6.2 16.4 0 22.6L169.4 256 36.9 388.5c-6.2 6.2-6.2 16.4 0 22.6s16.4 6.2 22.6 0L192 278.6 324.5 411.1z"/></svg>', |
|
]; |
|
// ##< app/icons ### |
|
|
|
public function __construct(private readonly Packages $packages) |
|
{ |
|
} |
|
|
|
public function enumIcon(FontAwesomeIconInterface|string $icon, string $cssClasses = 'fa-4', bool $fromSprite = false): string |
|
{ |
|
if (is_string($icon)) { |
|
$icon = RegularIcon::from($icon); |
|
} |
|
|
|
$id = $icon->getStyle().'-'.$icon->value; |
|
if (!isset(self::ICONS[$id])) { |
|
throw new \RuntimeException(sprintf('The icon %s does not exist. Did you forget to run `bin/console app:icons`?', $id)); |
|
} |
|
|
|
if ($fromSprite) { |
|
return $this->fromSprite($icon, $cssClasses); |
|
} |
|
|
|
return sprintf(self::ICONS[$icon->getStyle().'-'.$icon->value], $cssClasses); |
|
} |
|
|
|
public function getFunctions(): array |
|
{ |
|
return [ |
|
new TwigFunction('enumIcon', $this->enumIcon(...), ['is_safe' => ['html']]), |
|
// new TwigFunction('lightIcon', $this->getLightIcon(...), ['is_safe' => ['html']]), |
|
new TwigFunction('regularIcon', $this->getRegularIcon(...), ['is_safe' => ['html']]), |
|
// new TwigFunction('solidIcon', $this->getSolidIcon(...), ['is_safe' => ['html']]), |
|
// new TwigFunction('brandIcon', $this->getBrandIcon(...), ['is_safe' => ['html']]), |
|
]; |
|
} |
|
|
|
public function getTests(): array |
|
{ |
|
return [ |
|
new TwigTest('enumIcon', $this->isEnumIcon(...)), |
|
]; |
|
} |
|
|
|
public function isEnumIcon(mixed $object): bool |
|
{ |
|
return $object instanceof FontAwesomeIconInterface; |
|
} |
|
|
|
// public function getLightIcon(string|array $icon, ?string $cssClasses = 'fa-4', bool $fromSprite = false): string |
|
// { |
|
// if (is_array($icon)) { |
|
// $icon = $this->findIconInArray($icon); |
|
// } |
|
|
|
// return $this->enumIcon(LightIcon::from($icon), $cssClasses, $fromSprite); |
|
// } |
|
|
|
public function getRegularIcon(string|array $icon, ?string $cssClasses = 'fa-4', bool $fromSprite = false): string |
|
{ |
|
if (is_array($icon)) { |
|
$icon = $this->findIconInArray($icon); |
|
} |
|
|
|
return $this->enumIcon(RegularIcon::from($icon), $cssClasses, $fromSprite); |
|
} |
|
|
|
// public function getSolidIcon(string|array $icon, ?string $cssClasses = 'fa-4', bool $fromSprite = false): string |
|
// { |
|
// if (is_array($icon)) { |
|
// $icon = $this->findIconInArray($icon); |
|
// } |
|
|
|
// return $this->enumIcon(SolidIcon::from($icon), $cssClasses, $fromSprite); |
|
// } |
|
|
|
// public function getBrandIcon(string|array $icon, ?string $cssClasses = 'fa-4', bool $fromSprite = false): string |
|
// { |
|
// if (is_array($icon)) { |
|
// $icon = $this->findIconInArray($icon); |
|
// } |
|
|
|
// return $this->enumIcon(BrandIcon::from($icon), $cssClasses, $fromSprite); |
|
// } |
|
|
|
private function findIconInArray(array $icons): string |
|
{ |
|
foreach ($icons as $icon => $condition) { |
|
if (true === $condition) { |
|
return $icon; |
|
} |
|
} |
|
|
|
throw new \RuntimeException(sprintf('None of the available icons was active: %s', implode(array_keys($icons)))); |
|
} |
|
|
|
/** |
|
* Load an icon from the generated SVG sprite. |
|
* |
|
* Use if you are loading a LOT of the same icons on one page, and the SVG code is long. If this is not the case, |
|
* please use {@link getIcon()} |
|
*/ |
|
private function fromSprite(FontAwesomeIconInterface $icon, string $cssClasses = 'fa-4'): string |
|
{ |
|
return |
|
($cssClasses ? '<svg class="'.$cssClasses.'">' : '<svg>'). |
|
'<use xlink:href="'.$this->packages->getUrl('build/images/sprites/icons.svg').'#'.$icon->getStyle().'-'.$icon->value.'"></use>'. |
|
'</svg>'; |
|
} |
|
} |