14 Commits
0.0.1 ... 0.0.6

Author SHA1 Message Date
Brabli
a4344687d4 Add cursor pointer class on hover 2022-08-29 20:29:04 +01:00
Brabli
4ec6224b25 Remove space 2022-08-29 20:27:48 +01:00
Brabli
7a3366c2da Add group hover 2022-08-29 20:12:55 +01:00
Brabli
78a321137e Get hover colours added 2022-08-29 20:08:27 +01:00
Brabli
5e3756773e Get tests passing 2022-08-29 20:01:39 +01:00
Brabli
6553d0d32f Change method name 2022-08-29 19:43:18 +01:00
Brabli
92eee8fa04 Add info 2022-08-29 19:41:57 +01:00
Brabli
e12eceed26 Adjust comment spacing 2022-08-29 19:41:54 +01:00
Brabli
27dfa0af2e Test for black fill and stroke style removal 2022-08-29 19:31:27 +01:00
Brabli
3e4b948569 Add example config 2022-08-29 19:21:08 +01:00
Brabli
e72ce28af4 Remove args from services.yaml 2022-08-29 19:18:47 +01:00
Brabli
4329780c39 See if moving args down works 2022-08-29 18:38:48 +01:00
Brabli
f7efd93cec Add dollar sign prefix 2022-08-29 18:32:35 +01:00
Brabli
bac02c285f Change key 2022-08-29 18:31:35 +01:00
5 changed files with 84 additions and 30 deletions

View File

@@ -1,3 +1,22 @@
# PCM Icon Bundle # PCM Icon Bundle
# WIP DON'T USE YET # WIP DON'T USE YET
Example config:
```yml
pcm_icon:
directories:
- '%kernel.project_dir%/public/icons'
palletes:
primary:
stroke: 'stroke-primary'
fill: 'fill-primary'
white:
stroke: 'stroke-white'
fill: 'fill-white'
red:
stroke: 'stroke-red-400'
fill: 'fill-red-400'
```
Remember to add './config/packages/*.yaml' as a value in your Tailwind config content array.

View File

@@ -6,16 +6,6 @@ services:
pcm_icon.icon_extension: pcm_icon.icon_extension:
public: true public: true
class: Pcm\IconBundle\Twig\Functions\IconExtension class: Pcm\IconBundle\Twig\Functions\IconExtension
args:
directories:
- '%kernel.project_dir%/public/icons'
palletes:
- primary:
stroke: stroke-primary,
fill: fill-primary
- white:
stroke: stroke-white,
fill: fill-white
Pcm\IconBundle\Twig\Functions\IconExtension: Pcm\IconBundle\Twig\Functions\IconExtension:
public: false public: false

View File

@@ -16,7 +16,8 @@ final class IconExtension extends AbstractExtension
'icon' => null, 'icon' => null,
'title' => null, 'title' => null,
'size' => self::DEFAULT_SIZE, 'size' => self::DEFAULT_SIZE,
'colour' => 'primary' 'colour' => 'primary',
'hover' => null
]; ];
public function __construct(private array $directories, private array $palletes) public function __construct(private array $directories, private array $palletes)
@@ -62,10 +63,11 @@ final class IconExtension extends AbstractExtension
* @param array $options * @param array $options
* ``` * ```
* $options = [ * $options = [
* 'icon' => (string) Which icon to use * 'icon' => (string) 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
* ] * ]
* ``` * ```
*/ */
@@ -77,10 +79,18 @@ final class IconExtension extends AbstractExtension
$rawSvgMarkup = $this->getSvgMarkup($iconFilepath); $rawSvgMarkup = $this->getSvgMarkup($iconFilepath);
$cleanSvgMarkup = $this->cleanSvgMarkup($rawSvgMarkup); $cleanSvgMarkup = $this->cleanSvgMarkup($rawSvgMarkup);
$mainPallete = $this->getMainPallete($options['colour']); $mainPallete = $this->getPallete($options['colour']);
$colourClasses = "{$mainPallete['stroke']} {$mainPallete['fill']}";
if (null !== $options['hover']) {
$hoverPallete = $this->getPallete($options['hover']);
$colourClasses .= " cursor-pointer hover:{$hoverPallete['stroke']} hover:{$hoverPallete['fill']} group-hover:{$hoverPallete['stroke']} group-hover:{$hoverPallete['fill']}";
}
$xml = new \SimpleXMLElement($cleanSvgMarkup); $xml = new \SimpleXMLElement($cleanSvgMarkup);
$xml = $this->addAttributeToXmlElement($xml, 'class', $mainPallete['stroke'] . ' ' . $mainPallete['fill']); $xml = $this->addAttributeToXmlElement($xml, 'class', $colourClasses);
$markup = $this->removeXMLDeclaration($xml->saveXML()); $markup = $this->removeXMLDeclaration($xml->saveXML());
if ($this->isNonEmptyString($options['title'])) if ($this->isNonEmptyString($options['title']))
@@ -126,7 +136,7 @@ final class IconExtension extends AbstractExtension
return preg_replace('/<title>.*<\/title>/', '', $markup); return preg_replace('/<title>.*<\/title>/', '', $markup);
} }
private function getMainPallete(string $palleteName): array private function getPallete(string $palleteName): array
{ {
if (array_key_exists($palleteName, $this->palletes)) if (array_key_exists($palleteName, $this->palletes))
return $this->palletes[$palleteName]; return $this->palletes[$palleteName];
@@ -179,25 +189,15 @@ final class IconExtension extends AbstractExtension
private function removeBlackStrokeAttributes(string $content): string private function removeBlackStrokeAttributes(string $content): string
{ {
return preg_replace('/stroke="\s*(#0{6}|#000|rgb\(\s*0,\s*0,\s*0\s*\)|black)\s*"/', '', $content); return preg_replace('/stroke(=|:)"?\s*(#0{6}|#000|rgb\(\s*0,\s*0,\s*0\s*\)|black)\s*"?/', '', $content);
} }
private function removeBlackFillAttributes(string $content): string private function removeBlackFillAttributes(string $content): string
{ {
return preg_replace('/fill="\s*(#0{6}|#000|rgb\(\s*0,\s*0,\s*0\s*\)|black)\s*"/', '', $content); return preg_replace('/fill(=|:)"?\s*(#0{6}|#000|rgb\(\s*0,\s*0,\s*0\s*\)|black)\s*"?/', '', $content);
} }
} }
class IconNotFound extends \Exception {}; class IconNotFound extends \Exception {};
class PalleteNotFound extends \Exception {}; class PalleteNotFound extends \Exception {};
// class="stroke-neutral-400 fill-neutral-400"
// hover:stroke-ses-highlight
// group-hover:stroke-ses-highlight
// hover:fill-ses-highlight
// group-hover:fill-ses-highlight
// cursor-pointer

View File

@@ -200,6 +200,15 @@ class IconExtensionTest extends TestCase
$this->assertDoesNotMatchRegularExpression('/stroke="\s*rgb\(0,\s*0,\s*0\)\s*"/', $content); $this->assertDoesNotMatchRegularExpression('/stroke="\s*rgb\(0,\s*0,\s*0\)\s*"/', $content);
} }
public function testBlackStrokeStylesAreRemoved(): void
{
$content = $this->icon->renderIcon(['icon' => self::ICON]);
$this->assertDoesNotMatchRegularExpression('/stroke:\s*#000\s*/', $content);
$this->assertDoesNotMatchRegularExpression('/stroke:\s*#000000\s*/', $content);
$this->assertDoesNotMatchRegularExpression('/stroke:\s*black\s*/', $content);
$this->assertDoesNotMatchRegularExpression('/stroke:\s*rgb\(0,\s*0,\s*0\)\s*/', $content);
}
public function testBlackFillAttributeValuesAreRemoved(): void public function testBlackFillAttributeValuesAreRemoved(): void
{ {
$content = $this->icon->renderIcon(['icon' => self::ICON]); $content = $this->icon->renderIcon(['icon' => self::ICON]);
@@ -209,7 +218,16 @@ class IconExtensionTest extends TestCase
$this->assertDoesNotMatchRegularExpression('/fill="\s*rgb\(0,\s*0,\s*0\)\s*"/', $content); $this->assertDoesNotMatchRegularExpression('/fill="\s*rgb\(0,\s*0,\s*0\)\s*"/', $content);
} }
public function testThrowsIfPalleteIsNotFound(): void public function testBlackFillStylesAreRemoved(): void
{
$content = $this->icon->renderIcon(['icon' => self::ICON]);
$this->assertDoesNotMatchRegularExpression('/fill:\s*#000\s*/', $content);
$this->assertDoesNotMatchRegularExpression('/fill:\s*#000000\s*/', $content);
$this->assertDoesNotMatchRegularExpression('/fill:\s*black\s*/', $content);
$this->assertDoesNotMatchRegularExpression('/fill:\s*rgb\(0,\s*0,\s*0\)\s*/', $content);
}
public function testThrowsIfColourPalleteIsNotFound(): void
{ {
$this->expectException(PalleteNotFound::class); $this->expectException(PalleteNotFound::class);
$this->icon->renderIcon(['icon' => self::ICON, 'colour' => 'red']); $this->icon->renderIcon(['icon' => self::ICON, 'colour' => 'red']);
@@ -222,5 +240,31 @@ class IconExtensionTest extends TestCase
$this->assertMatchesRegularExpression('/<svg.*?class=".*?stroke-white?.*>/', $contents); $this->assertMatchesRegularExpression('/<svg.*?class=".*?stroke-white?.*>/', $contents);
} }
public function testThrowsIfHoverPalleteIsNotFound(): void
{
$this->expectException(PalleteNotFound::class);
$this->icon->renderIcon(['icon' => self::ICON, 'hover' => 'red']);
}
public function testSvgClassContainsHoverPalleteClasses(): void
{
$contents = $this->icon->renderIcon(['icon' => self::ICON, 'hover' => 'white']);
$this->assertMatchesRegularExpression('/<svg.+class=".*cursor-pointer.*".*>/', $contents);
$this->assertMatchesRegularExpression('/<svg.+class=".*hover:fill-white.*".*>/', $contents);
$this->assertMatchesRegularExpression('/<svg.+class=".*hover:stroke-white.*".*>/', $contents);
$this->assertMatchesRegularExpression('/<svg.+class=".*group-hover:fill-white.*".*>/', $contents);
$this->assertMatchesRegularExpression('/<svg.+class=".*group-hover:stroke-white.*".*>/', $contents);
}
public function testSvgClassContainsHoverAndColourPalleteClasses(): void
{
$contents = $this->icon->renderIcon(['icon' => self::ICON, 'hover' => 'white', 'colour' => 'primary']);
$this->assertMatchesRegularExpression('/<svg.+class=".*fill-primary.*".*>/', $contents);
$this->assertMatchesRegularExpression('/<svg.+class=".*stroke-primary.*".*>/', $contents);
$this->assertMatchesRegularExpression('/<svg.+class=".*cursor-pointer.*".*>/', $contents);
$this->assertMatchesRegularExpression('/<svg.+class=".*hover:fill-white.*".*>/', $contents);
$this->assertMatchesRegularExpression('/<svg.+class=".*hover:stroke-white.*".*>/', $contents);
$this->assertMatchesRegularExpression('/<svg.+class=".*group-hover:fill-white.*".*>/', $contents);
$this->assertMatchesRegularExpression('/<svg.+class=".*group-hover:stroke-white.*".*>/', $contents);
}
} }

View File

@@ -6,4 +6,5 @@
<line fill="black"></line> <line fill="black"></line>
<line x1="256" y1="112" x2="256" y2="400" width="101" height="101" style="fill: none; stroke: rgb(0,0, 0); stroke-linecap: round; stroke-linejoin: round; stroke-width: 32px;"></line> <line x1="256" y1="112" x2="256" y2="400" width="101" height="101" style="fill: none; stroke: rgb(0,0, 0); stroke-linecap: round; stroke-linejoin: round; stroke-width: 32px;"></line>
<line x1="400" y1="256" x2="112" y2="256" width="102" height="102" style="fill: none; stroke: #000; stroke-linecap: round; stroke-linejoin: round; stroke-width: 32px;"></line> <line x1="400" y1="256" x2="112" y2="256" width="102" height="102" style="fill: none; stroke: #000; stroke-linecap: round; stroke-linejoin: round; stroke-width: 32px;"></line>
<polyline points="112 244 256 100 400 244" style="fill:#000;fill:#000000;fill: black;fill:rgb(0,0,0);stroke:#000;stroke:#000000;stroke:black;stroke:rgb(0, 0, 0);stroke-linecap:round;stroke-linejoin:round;stroke-width:48px"/>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 631 B

After

Width:  |  Height:  |  Size: 860 B