Add 'classes' option to add extra classes

This commit is contained in:
Brabli
2023-01-03 10:58:16 +00:00
parent d5278f3473
commit 87a6204f25
2 changed files with 45 additions and 13 deletions

View File

@@ -16,7 +16,8 @@ final class IconExtension extends AbstractExtension
'title' => null, 'title' => null,
'size' => self::DEFAULT_SIZE, 'size' => self::DEFAULT_SIZE,
'colour' => 'primary', 'colour' => 'primary',
'hover' => null 'hover' => null,
'classes' => [],
]; ];
public function __construct(private array $directories, private array $palletes) public function __construct(private array $directories, private array $palletes)
@@ -33,10 +34,10 @@ final class IconExtension extends AbstractExtension
if (empty($this->palletes)) if (empty($this->palletes))
throw new \InvalidArgumentException('Palletes array must contain at least one pallet!'); throw new \InvalidArgumentException('Palletes array must contain at least one pallet!');
$pelletesContainNonarray = array_reduce($this->palletes, $palletesContainNonarray = array_reduce($this->palletes,
fn($notArray, $path) => $notArray || !is_array($path)); fn($notArray, $path) => $notArray || !is_array($path));
if ($pelletesContainNonarray) if ($palletesContainNonarray)
throw new \TypeError('Palletes array must only contain arrays!'); throw new \TypeError('Palletes array must only contain arrays!');
foreach ($this->palletes as $pallete) { foreach ($this->palletes as $pallete) {
@@ -69,11 +70,14 @@ final class IconExtension extends AbstractExtension
* @param array $options * @param array $options
* ``` * ```
* $options = [ * $options = [
* 'icon' => (string) Which icon to use * 'icon' => (string) REQUIRED Which icon to use
* 'title' => (?string) Text to appear on mouse hover * 'title' => (?string) Text to appear on mouse hover
* 'size' => (int) Height and width in px * 'size' => (int) Height and width in px
* 'colour' => (string) Main colour pallete * 'colour' => (string) Main colour pallete
* 'hover' => (?string) Hover colour pallete * 'hover' => (?string) Hover colour pallete
* 'classes' => (array) Additional classes to add to the icon.
* Use with caution as this can potentially
* cause Tailwind class conflicts!
* ] * ]
* ``` * ```
*/ */
@@ -81,14 +85,22 @@ final class IconExtension extends AbstractExtension
{ {
$options = $this->getMergedOptions($userOptions); $options = $this->getMergedOptions($userOptions);
$svg = $this->getSanitisedIconSvg($options['icon']); $svg = $this->getSanitisedIconSvg($options['icon']);
$colourClasses = $this->getColourClasses($options['colour'], $options['hover']); $colourClasses = $this->getColourClasses($options['colour'], $options['hover']);
$svg = $this->addClassesToSvg($svg, $colourClasses); $extraClasses = $this->getExtraClasses($options['classes']);
$svg = $this->addClassesToSvg($svg, trim($colourClasses.' '.$extraClasses));
$svg = $this->addTitleToSvgIfNotNull($svg, $options['title']); $svg = $this->addTitleToSvgIfNotNull($svg, $options['title']);
$svg = $this->setSvgHeightAndWidth($svg, $options['size']); $svg = $this->setSvgHeightAndWidth($svg, $options['size']);
return $svg; return $svg;
} }
private function getExtraClasses(array $extraClasses): string
{
return implode(' ', $extraClasses);
}
private function getMergedOptions(array $userOptions): array private function getMergedOptions(array $userOptions): array
{ {
$this->throwIfUnrecognisedOptionExists($userOptions); $this->throwIfUnrecognisedOptionExists($userOptions);

View File

@@ -300,6 +300,26 @@ class IconExtensionTest extends TestCase
$this->assertMatchesRegularExpression('/<svg.+class=".*group-hover:stroke-white.*".*>/', $contents); $this->assertMatchesRegularExpression('/<svg.+class=".*group-hover:stroke-white.*".*>/', $contents);
} }
public function testExtraClassesThrowsIfNotAnArray(): void
{
$this->expectException(\TypeError::class);
$this->icon->renderIcon(['icon' => self::ICON, 'classes' => 'string_value']);
}
public function testExtraClassesGetAdded(): void
{
$contents = $this->icon->renderIcon(['icon' => self::ICON, 'classes' => ['abc', 'def']]);
$this->assertMatchesRegularExpression('/<svg.+class=".*abc.*".*>/', $contents);
$this->assertMatchesRegularExpression('/<svg.+class=".*def.*".*>/', $contents);
}
public function testAddingExtraClassesDoesntStripAwayColourClasses(): void
{
$contents = $this->icon->renderIcon(['icon' => self::ICON, 'classes' => ['abc']]);
$this->assertMatchesRegularExpression('/<svg.+class=".*abc.*".*>/', $contents);
$this->assertMatchesRegularExpression('/<svg.+class=".*fill-primary.*".*>/', $contents);
}
public function testThrowsIfInvalidOptionPassed(): void public function testThrowsIfInvalidOptionPassed(): void
{ {
$this->expectException(\InvalidArgumentException::class); $this->expectException(\InvalidArgumentException::class);