From 57a7c41e1e79e38aed029d3e6ae690b04344c99e Mon Sep 17 00:00:00 2001 From: indykoning <15870933+indykoning@users.noreply.github.com> Date: Wed, 11 May 2022 14:38:11 +0200 Subject: [PATCH] Defer icons to icons stack to reduce DOM count (#191) * Defer icons to icons stack to reduce DOM count * Create test for deferred icon * Update readme with more intuitive attribute Co-authored-by: Dries Vints Co-authored-by: Dries Vints --- README.md | 20 ++++++++++++++++++++ src/Svg.php | 25 ++++++++++++++++++++++++- tests/SvgTest.php | 11 +++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c3c0d64..9bf41d4 100644 --- a/README.md +++ b/README.md @@ -383,6 +383,26 @@ Or any other attributes for that matter: > ⚠️ Note that with Blade components, using a prefix is always required, even when referencing icons from the default set. +#### Deferring icons + +When you're using the same icon in lots of places on the page the DOM element count may explode upwards. +To remedy this you can add the defer attribute to the components: + +```blade + +``` + +This will push the icons to the stack "bladeicons", you should load this stack at the bottom of your page + +```blade + ... + + + +``` + #### 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: diff --git a/src/Svg.php b/src/Svg.php index 9a720a5..3f04aa8 100644 --- a/src/Svg.php +++ b/src/Svg.php @@ -18,7 +18,7 @@ final class Svg implements Htmlable public function __construct(string $name, string $contents, array $attributes = []) { $this->name = $name; - $this->contents = $contents; + $this->contents = $this->deferContent($contents, $attributes['defer'] ?? false); $this->attributes = $attributes; } @@ -40,4 +40,27 @@ public function toHtml(): string $this->contents, ); } + + protected function deferContent($contents, $defer = false) + { + if (! $defer) { + return $contents; + } + + $svgContent = strip_tags($contents, ['circle', 'ellipse', 'line', 'path', 'polygon', 'polyline', 'rect']); + $hash = 'icon-'.md5($svgContent); + $contents = str_replace($svgContent, strtr('', [':href' => '#'.$hash]), $contents); + $contents .= << + {$svgContent} + + @endpush + @endonce + BLADE; + + return $contents; + } } diff --git a/tests/SvgTest.php b/tests/SvgTest.php index ed98720..e6648c2 100644 --- a/tests/SvgTest.php +++ b/tests/SvgTest.php @@ -25,6 +25,17 @@ public function it_can_compile_to_html() $this->assertSame('', $svg->toHtml()); } + /** @test */ + public function it_can_compile_to_defered_html() + { + $svgPath = ''; + $svg = new Svg('heroicon-o-arrow-right', ''.$svgPath.'', ['defer' => true]); + + $svgHtml = $svg->toHtml(); + $this->assertStringContainsString('', $svgHtml); + $this->assertStringContainsString($svgPath, $svgHtml); + } + /** @test */ public function it_can_compile_with_attributes() {