Skip to content

Commit

Permalink
Add ability to provide own defer hash (#201)
Browse files Browse the repository at this point in the history
* Add ability to provide own defer hash

- Ideal when you want to reuse deferred icons in your React/Vue components
- Related PR discussion #200

* Update docs

* Update Svg.php

* Update README.md

Co-authored-by: Dries Vints <[email protected]>
  • Loading branch information
pionl and driesvints authored Sep 28, 2022
1 parent 26278e4 commit acbe0b4
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 3 deletions.
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,23 @@ This will push the icons to the stack "bladeicons", you should load this stack a
</html>
```

##### Using deferred icons in JavaScript

You can re-use your icons from blade in your JavaScript rendered views by providing a custom defer value that will be used
as an identifier:

```blade
<x-icon-camera defer="my-custom-hash" />
```

Then, in your JavaScript, create an `svg` element with `use` and `href="#icon-{your-hash}"` attribute.

```javascript
function icon() {
return <svg><use href="#icon-my-custom-hash"></use></svg>
}
```

#### Default Component

If you don't want to use the component syntax from above you can also make use of the default `Icon` component that ships with Blade Icons. Simply pass the icon name through the `$name` attribute:
Expand Down
6 changes: 3 additions & 3 deletions src/Svg.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,14 @@ public function toHtml(): string
);
}

protected function deferContent($contents, $defer = false)
protected function deferContent(string $contents, $defer = false): string
{
if (! $defer) {
if ($defer === false) {
return $contents;
}

$svgContent = strip_tags($contents, ['circle', 'ellipse', 'line', 'path', 'polygon', 'polyline', 'rect', 'g']);
$hash = 'icon-'.md5($svgContent);
$hash = 'icon-'.(is_string($defer) ? $defer : md5($svgContent));
$contents = str_replace($svgContent, strtr('<use href=":href"></use>', [':href' => '#'.$hash]), $contents);
$contents .= <<<BLADE
Expand Down
35 changes: 35 additions & 0 deletions tests/SvgTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,23 @@ public function it_can_compile_to_defered_html()
@endonce', $svgHtml);
}

/** @test */
public function it_can_compile_to_defered_html_custom_defer()
{
$svgPath = '<path d="M14 5l7 7m0 0l-7 7m7-7H3"></path>';
$svg = new Svg('heroicon-o-arrow-right', '<svg>'.$svgPath.'</svg>', ['defer' => 'my-custom-hash']);

$svgHtml = $svg->toHtml();
$this->assertEquals('<svg defer="my-custom-hash"><use href="#icon-my-custom-hash"></use></svg>
@once("icon-my-custom-hash")
@push("bladeicons")
<g id="icon-my-custom-hash">
<path d="M14 5l7 7m0 0l-7 7m7-7H3"></path>
</g>
@endpush
@endonce', $svgHtml);
}

/** @test */
public function it_can_compile_to_defered_html_with_group()
{
Expand All @@ -60,6 +77,24 @@ public function it_can_compile_to_defered_html_with_group()
@endonce', $svgHtml);
}

/** @test */
public function it_can_compile_to_defered_html_with_group_custom_defer()
{
$svgPath = '<g id="test" transform="translate(1 1)"><path d="M14 5l7 7m0 0l-7 7m7-7H3"></path></g>';
$svg = new Svg('heroicon-o-arrow-right', '<svg>'.$svgPath.'</svg>', ['defer' => 'my-custom-hash']);

$svgHtml = $svg->toHtml();

$this->assertEquals('<svg defer="my-custom-hash"><use href="#icon-my-custom-hash"></use></svg>
@once("icon-my-custom-hash")
@push("bladeicons")
<g id="icon-my-custom-hash">
<g id="test" transform="translate(1 1)"><path d="M14 5l7 7m0 0l-7 7m7-7H3"></path></g>
</g>
@endpush
@endonce', $svgHtml);
}

/** @test */
public function it_can_compile_to_defered_html_with_group_and_whitespace()
{
Expand Down

0 comments on commit acbe0b4

Please sign in to comment.