Giter VIP home page Giter VIP logo

blade-icons's Introduction

Blade Icons

Tests Coding Standards Latest Stable Version Total Downloads

A package to easily make use of SVG icons in your Laravel Blade views. Originally "Blade SVG" by Adam Wathan.

Turn...

<!-- camera.svg -->
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor" class="w-6 h-6">
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 9a2 2 0 012-2h.93a2 2 0 001.664-.89l.812-1.22A2 2 0 0110.07 4h3.86a2 2 0 011.664.89l.812 1.22A2 2 0 0018.07 7H19a2 2 0 012 2v9a2 2 0 01-2 2H5a2 2 0 01-2-2V9z"/>
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 13a3 3 0 11-6 0 3 3 0 016 0z"/>
</svg>

Into...

<x-icon-camera class="w-6 h-6" />

Or into...

@svg('camera', 'w-6 h-6')

Looking for a specific icon? Try our icon search: https://blade-ui-kit.com/blade-icons#search

Any sponsorship to help fund development is greatly appreciated ❤️

Icon Packages

Blade Icons is a base package to make it easy for you to use SVG icons in your app. In addition, there's also quite some third party icon set packages. Thanks to the community for contributing these!

We're not accepting requests to build new icon packages ourselves but you can start building your own.

Requirements

  • PHP 7.4 or higher
  • Laravel 8.0 or higher

Installation

Install the package with composer:

composer require blade-ui-kit/blade-icons

Then, publish the configuration and uncomment the default icon set:

php artisan vendor:publish --tag=blade-icons

Make sure that the path defined for this icon set exists. By default it's resources/svg. Your SVG icons will need to be placed in this directory.

Upgrading

Please refer to the upgrade guide when upgrading the library.

Caching

When working with Blade Icons, and third party icon sets in particular, you'll often be working with large icon sets. This can slow down your app tremendously, especially when making use of Blade components. To solve this issue, Blade Icons ships with caching support. To enable icon caching you can run the following command:

php artisan icons:cache

This will create a blade-icons.php file in bootstrap/cache similar to the packages.php cached file. It'll contain a manifest of all known sets and icons with their path locations.

Caching icons means you won't be able to add extra icons, change paths for icon sets or install/remove icon packages. To do so make sure you first clear the icons cache and cache after you've made these changes:

php artisan icons:clear

It's a good idea to add the icons:cache command as part of your deployment pipeline and always cache icons in production.

Alternatively, you may choose to disable Blade components entirely.

Also, when adding new icons, renaming directories in your icon paths, it's always a good idea to clear your views before refreshing the page:

php artisan view:clear

Configuration

Defining Sets

Blade Icons support multiple sets. You can define these by passing a key/value combination in the blade-icons.php config file's sets setting:

<?php

return [
    'sets' => [
        'default' => [
            'path' => 'resources/svg',
        ],
    ],
];

Feel free to add as many sets as you wish. Blade Icons ships with a default set for your app which you may adjust to your liking.

Icon Paths

If you wanted to add icons from a different directory in your app, say resources/images/svg, you can set it like this:

<?php

return [
    'sets' => [
        'default' => [
            'path' => 'resources/images/svg',
        ],
    ],
];

Warning Always make sure you're pointing to existing directories.

Multiple Paths

In addition to a single path, you may define multiple paths for a single set with the paths option instead:

<?php

return [
    'sets' => [
        'default' => [
            'paths' => [
                'resources/images/icon-set',
                'resources/images/other-icon-set',
            ],
        ],
    ],
];

This gives you the benefit from grouping icons from different paths under a single set where you can define the same prefix and default classes.

Warning When using multiple paths instead of one, Blade Icons will return the first icon it finds when an icon name is present in more than one path. Please ensure you use unique icon names when registering multiple paths if you want to retrieve the correct icon.

Filesystem Disk

If you host your icons on an external filesystem storage you can set the disk option for an icon set to a disk defined in your filesystems.php config file. For example, you might store your icons on an AWS S3 bucket which is set in your filesystems.php config file with a disk key of s3-icons:

<?php

return [
    'sets' => [
        'default' => [
            'path' => '/',
            'disk' => 's3-icons',
        ],
    ],
];

And from now on our default set will pull the icons from the S3 bucket. Also notice we've adjusted the path to / because we store our icons in the root directory of this S3 bucket. If you have several icon sets uploaded to the same disk you can set your paths accordingly:

<?php

return [
    'sets' => [
        'heroicons' => [
            'path' => 'heroicons',
            'disk' => 's3-icons',
            'prefix' => 'heroicon',
        ],
        'zondicons' => [
            'path' => 'zondicons',
            'disk' => 's3-icons',
            'prefix' => 'zondicon',
        ],
    ],
];

Fallback Icons

If you want to provide a fallback icon when an icon cannot be found, you may define the fallback option on a specific set:

<?php

return [
    'sets' => [
        'default' => [
            'fallback' => 'cake',
        ],
    ],
];

Now when you try to resolve a non-existing icon for the default icon set, it'll return the rendered "cake" icon instead.

You can also provide a global fallback icon instead. This icon will be used when an icon cannot be found and the set doesn't have its own fallback icon defined. It can reference any icon from any registered icon set.

<?php

return [
    'fallback' => 'heroicon-cake',
];

Note There's one caveat when using fallback icons and that is that they don't work when using Blade Components. In this case, Laravel will throw an exception that the component cannot be found. If you want to make use of fallback icons please consider one of the other usages.

Prefixing Icons

In the default icon set the icon prefix will be applied to every icon, but you're free to adjust this in the blade-icons.php config file:

<?php

return [
    'sets' => [
        'default' => [
            'prefix' => 'icon',
        ],
    ],
];

Defining a prefix for every set is required and every prefix should be unique.

When referencing icons with the Blade directive or helper you can omit the prefix to reference icons from the default set. When referencing icons from other sets, using the prefix is required.

When an icon in the default set has a name which collides with a prefix from a set then the icon from the default set is retrieved first.

Please note that it's best practice that your icons themselves do not have the prefix in their name. So if you have a prefix in your set called icon and your icons are named icon-example.svg you should rename them to example.svg. Otherwise you can run into unexpected name resolving issues.

It's also important to note that icon prefixes cannot contain dashes (-) as this is the delimiter which we use to split it from the rest of the icon name.

Default Classes

You can optionally define classes which will be applied to every icon by filling in the class setting in your blade-icons.php config file:

<?php

return [
    'class' => 'icon icon-default',
];

If you don't want any classes to be applied by default then leave this as an empty string. Additionally, the same option is available in sets so you can set default classes on every set.

The sequence in which classes get applied is <global classes> <set classes> <explicit classes>. You can always override this by passing an explicit class with your attributes. Component classes cannot be overridden.

Default Attributes

You can also optionally define some attributes which will be added to every icon in the attributes setting of your blade-icons.php config file:

<?php

return [
    'attributes' => [
        'width' => 50,
        'height' => 50,
    ],
];

This always needs to be an associative array. Additionally, the same option is available in sets so you can set default attributes on every set.

The sequence in which classes get applied is default attributes / set attributes / explicit attributes where the latter overwrites the former. It is not possible to overwrite existing attributes on SVG icons. If you already have attributes defined on icons which you want to override, remove them first.

Usage

There are several ways of inserting icons into your Blade templates. We personally recommend using Blade components, but you can also make use of a Blade directive if you wish.

Components

The easiest way to get started with using icons from sets are Blade components:

<x-icon-camera/>

Icons in subdirectories can be referenced using dot notation:

<x-icon-solid.camera/>

You can also pass classes to your icon components (default classes will be applied as well):

<x-icon-camera class="icon-lg"/>

Or any other attributes for that matter:

<x-icon-camera class="icon-lg" id="settings-icon" style="color: #555" data-baz/>

Note 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:

<x-icon-camera defer />

This will push the icons to the stack "bladeicons", you should load this stack at the bottom of your page

   ...
    <svg hidden class="hidden">
        @stack('bladeicons')
    </svg>
</body>
</html>

Deferring icons is only possible using the <x-icon> component. This feature doesn't work with the @svg Blade directive or the svg() helper function.

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:

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

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

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:

<x-icon name="camera"/>

If you want to use a different name for this component instead you can customize the components.default option in your blade-icons.php config file:

<?php

return [
    'components' => [
        'default' => 'svg',
    ],
];

Then reference the default icon as follow:

<x-svg name="camera"/>

You can also completely disable this default component if you want by setting its name to null:

<?php

return [
    'components' => [
        'default' => null,
    ],
];

Disabling Components

Although they're enabled by default, if you don't wish to use components at all you may choose to disable them completely by setting the components.disabled setting in your blade-icons.php config file to true:

<?php

return [
    'components' => [
        'disabled' => true,
    ],
];

Doing this makes sense when you're only using the directive or the helper and can improve overall performance.

Directive

If components aren't really your thing you can make use of the Blade directive instead. If you defined a default icon class in your config and want to render a camera icon with an icon-lg class you can do that like so:

@svg('camera', 'icon-lg')

Any additionally attributes can be passed as a third array argument, and they'll be rendered on the svg element:

@svg('camera', 'icon-lg', ['id' => 'settings-icon'])

If you don't have a class to be defined you can also pass these attributes as the second parameter:

@svg('camera', ['id' => 'settings-icon'])

If you want to override the default classes, pass in the class as an attribute:

@svg('camera', ['class' => 'icon-lg'])

Attributes without a key, are supported too:

@svg('camera', ['data-foo'])

Helper

If you'd like, you can use the svg helper to expose a fluent syntax for setting SVG attributes:

{{ svg('camera')->id('settings-icon')->dataFoo('bar')->dataBaz() }}

Building Packages

If you're interested in building your own third party package to integrate an icon set, it's pretty easy to do so. We've created a template repo for you to get started with. You can find the getting started instructions in its readme.

If you want to learn how to create packages we can recommend these two excellent courses:

Make sure to load your SVGs from the register method of your package's service provider. Provide the path to your SVGs and provide your own unique set name and component prefix:

use BladeUI\Icons\Factory;

public function register(): void
{
    $this->callAfterResolving(Factory::class, function (Factory $factory) {
        $factory->add('heroicons', [
            'path' => __DIR__.'/../resources/svg',
            'prefix' => 'heroicon',
        ]);
    });
}

Now your icons can be referenced using a component, directive or helper:

<x-heroicon-o-bell/>

@svg('heroicon-o-bell')

{{ svg('heroicon-o-bell') }}

Don't forget to make blade-ui-kit/blade-icons a requirement of your package's composer.json.

Generating Icons

Blade Icons also offers an easy way to generate icons for your packages. By defining a config file with predefined source and destination paths, you can make updating your icons a breeze.

First, start off by creating a generation.php config file in the config directory of your icon package. Next, you can define an array per icon set that you want to generate. Below is a full version of this file with explanation for every option. Only the source and destination options are required.

<?php

use Symfony\Component\Finder\SplFileInfo;

return [
    [
        // Define a source directory for the sets like a node_modules/ or vendor/ directory...
        'source' => __DIR__.'/../node_modules/heroicons/outline',

        // Define a destination directory for your icons. The below is a good default...
        'destination' => __DIR__.'/../resources/svg',

        // Strip an optional prefix from each source icon name...
        'input-prefix' => 'o-',

        // Set an optional prefix to applied to each destination icon name...
        'output-prefix' => 'o-',

        // Strip an optional suffix from each source icon name...
        'input-suffix' => '-o',

        // Set an optional suffix to applied to each destination icon name...
        'output-suffix' => '-o',

        // Enable "safe" mode which will prevent deletion of old icons...
        'safe' => true,

        // Call an optional callback to manipulate the icon with the pathname of the icon,
        // the settings from above and the original icon file instance...
        'after' => static function (string $icon, array $config, SplFileInfo $file) {
            // ...
        },
    ],

    // More icon sets...
];

See an example config/generation.php file for the Heroicons package.

After setting up your config file you can use the icon generation as follow from the root of your icon package directory:

vendor/bin/blade-icons-generate

Changelog

Check out the CHANGELOG in this repository for all the recent changes.

Maintainers

Blade Icons is developed and maintained by Dries Vints.

License

Blade Icons is open-sourced software licensed under the MIT license.

blade-icons's People

Contributors

2zt avatar adamwathan avatar afatmustafa avatar andreiio avatar brunocfalcao avatar calebporzio avatar catgofire avatar datlechin avatar driesvints avatar indykoning avatar itsmalikjones avatar juukie avatar kirill-znamenskiy avatar lasserafn avatar mallardduck avatar mansoorkhan96 avatar miclf avatar mvdnbrk avatar nuernbergera avatar olumby avatar owenvoke avatar pionl avatar robsontenorio avatar ryangjchandler avatar sadegh19b avatar sebastianpopp avatar sixlive avatar stijnvanouplines avatar stylecibot avatar swapnilsarwe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

blade-icons's Issues

Tooltip support

Hello,

I'm trying to make this work with bootstrap 4 but it does not work properly.

   <div data-toggle="tooltip" title="Tooltip Test">Wallet Balance
        <x-zondicon-question style="width: 15px; margin-left: 2px;" />
    </div>

Strip trailing slash from path

@svg('icon-ui.checkmark-circle') this works as expected, however <x-icon-ui.checkmark-circle/> does not. I'm sure I'm missing something really simple here 🤷🏻‍♂️

blade-icons.php

<?php

return [

    'sets' => [
        'default' => [
            'path' => 'resources/assets/svg/icons/',
            'prefix' => 'icon',
            'class' => '',
        ],
    ],
    'class' => '',
];

Automatic Sprite Sheet

Is it possible to automatically create optimised sprite sheets?

For example if you set 'automatic_spritesheet' => true when you use @icon('cog') it builds up a collection of the svgs used, then it prints out the spritesheet after the body, based on only the icons you've picked? So you can have individual .svg files in your asset folder still?

Thanks :)

Installing the package breaks other package's directives

I haven't been able to figure out why, but as soon as I install this package and make any change to my view (or do php artisan view:clear as well), it no longer recognizes spatie/laravel-permission directives.

My view just prints out the directives as text, like this:

@hasanyrole('Administrador|Ventas')
<x-menu.menu-item>
@endhasanyrole

I'm using Laravel 7.16

Using icons hosted on remote storage

Hello, thanks for this amazing package!

I see that we can customize the path for a given icon set, but what if the icons are not stored on the application server?

In our case, they would be served from our remote S3 storage.

In addition to path, are we able to define the URL?

Blade helper renaming proposal

Hello.
I was thinking about the package, when we're talking about SVG (scalable vector graphics), not every SVG is an "icon", it could be just a simple graphic or whatever.
Perhaps shouldn't we consider renaming the helper @icon to @svg? Wouldn't it be better and more semantic flexible to the package? (I know we go the svg_icon as well, but my complaining is about the word "icon".
What do you guys thinks?
Cheers!

Package requires publishing the config as the default config is not being read

Hey, first of all; thanks for this package!

I was wondering why my SVG logo was not being rendered as an inline image, as your default config clearly states 'inline' => true.

Turns out, your SvgFactory has an additional $config that is not being populated with the out-of-the-box config.

Simply publishing the config works as a "fix".

AlpineJS conditional classes

First of all, cool package! Very helpful!

I'm running into one problem and I'm not 100% sure this is a bug or a lack of knowledge on my end. I'd like to give the component a conditional class in AlpineJS, such as:

:class="{ 'text-gray-600': open }"

I haven't had the time yet to dig into this extensively, but I'm guessing this is related to the attribute parsing done in blade-icons. Does anyone have a suggestion how to pass the conditional class to the icon?

Error before publishing config.

Hey, I get the following error when trying to publish the config.

[ErrorException]
array_merge(): Argument #1 is not an array

I get it because of this line:

$config = array_merge(config('blade-svg'), [

This fixes it:

$config = array_merge((array) config('blade-svg'), [

Once I run art vendor:publish --provider="BladeSvg\BladeSvgServiceProvider" the line can be removed, as now it returns an array.

Peformance concerns

Hi,

I updated yesterday from the nothingworks/blade-svg package to the blade-ui-kit/blade-icons package and I'm seeing much higher CPU usage on my servers as well as a very large number of php slow log entries relating to the package on every single request.

I am using the owenvoke/blade-fontawesome add on.

It seems when there is a large number of icons, for instance the fontawesome package provides around 1,500 icons, it loads every single file in the filesystem on every request.

Looking at https://github.com/blade-ui-kit/blade-icons/blob/main/src/Factory.php#L68-L81 it loads all the files in the filesystem (whether or not they're used) on every page request:

But the previous package would only load them as they're used https://github.com/blade-ui-kit/blade-icons/blob/v0.3.4/src/SvgFactory.php#L105

As an example of the slow log I'm seeing on every request:

[07-Aug-2020 02:32:07]  [pool www] pid 8233
script_filename = /srv/public/index.php
[0x00007f5fa7616e40] hasChildren() /srv/vendor/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php:76
[0x00007f5fa7616dd0] hasChildren() /srv/vendor/symfony/finder/Iterator/SortableIterator.php:91
[0x00007f5fa7616d80] next() /srv/vendor/symfony/finder/Iterator/SortableIterator.php:91
[0x00007f5fa7616d30] next() /srv/vendor/symfony/finder/Iterator/SortableIterator.php:91
[0x00007f5fa7616cc0] iterator_to_array() /srv/vendor/symfony/finder/Iterator/SortableIterator.php:91
[0x00007f5fa7616c40] getIterator() /srv/vendor/symfony/finder/Finder.php:772
[0x00007f5fa7616b10] searchInDirectory() /srv/vendor/symfony/finder/Finder.php:614
[0x00007f5fa7616a60] getIterator() /srv/vendor/laravel/framework/src/Illuminate/Filesystem/Filesystem.php:460
[0x00007f5fa76169f0] iterator_to_array() /srv/vendor/laravel/framework/src/Illuminate/Filesystem/Filesystem.php:460
[0x00007f5fa7616970] allFiles() /srv/vendor/blade-ui-kit/blade-icons/src/Factory.php:71
[0x00007f5fa76168b0] registerComponents() /srv/vendor/blade-ui-kit/blade-icons/src/BladeIconsServiceProvider.php:49
[0x00007f5fa7616830] BladeUI\Icons\{closure}() /srv/vendor/laravel/framework/src/Illuminate/Container/Container.php:1141
[0x00007f5fa7616790] fireCallbackArray() /srv/vendor/laravel/framework/src/Illuminate/Container/Container.php:1105
[0x00007f5fa7616710] fireAfterResolvingCallbacks() /srv/vendor/laravel/framework/src/Illuminate/Container/Container.php:1090
[0x00007f5fa7616690] fireResolvingCallbacks() /srv/vendor/laravel/framework/src/Illuminate/Container/Container.php:711
[0x00007f5fa76165b0] resolve() /srv/vendor/laravel/framework/src/Illuminate/Foundation/Application.php:796
[0x00007f5fa7616510] resolve() /srv/vendor/laravel/framework/src/Illuminate/Container/Container.php:637
[0x00007f5fa7616490] make() /srv/vendor/laravel/framework/src/Illuminate/Foundation/Application.php:781
[0x00007f5fa7616400] make() /srv/vendor/laravel/framework/src/Illuminate/Container/Container.php:1284
[0x00007f5fa7616390] offsetGet() unknown:0

I've had to revert this package upgrade and move back to the deprecated old package which immediately solved the slowlog and cpu issues.

Installation is not working

In BladeIconsServiceProvider.php line 34:

Trying to access array offset on value of type null

Script @php artisan package:discover --ansi handling the post-autoload-dump event returned with error code 1

Installation failed, reverting ./composer.json to its original content.

Specifying different path and filename

I'm having difficulty showing an inline SVG for a path and filename not in the /svg directory

Could we perhaps have a way of avoiding using the svg directory and passing a directory and SVG filename to the getSvg function like this:


   public function getSvgUrl($name)
    {
        return $this->svgCache->get($name, function () use ($name) {
            return $this->svgCache[$name] = trim($this->files->get(public_path($name)));
        });
    }

Feature Request: Accept blade variables as SVG name

I would love to show SVGs based on a value in a model's attribute.

Here is what I tried:
@svg({{ $user->type }}) which throws an ugly error (syntax error, unexpected '<' (View: ).

Browsing through blade-svg's tests, this use case is not being considered up till now.
I could not find a work around and it might be a nice addition.

Option to have multiple fallbacks for dynamic or missing icon names

Hi Adam. I would like to have multiple fallbacks for icons that are either user/programatically generated with optional fallbacks where the existance of the icon by name is not always known.

This does what I need and may be of interest to you or your users...(only tested in my case* )
These changes will enable an array to be used as the icon name. The getSVG function loops the array returning the first 'found' icon. if none of the icons are found it returns the config default icon.

*how I use it (I've added a few fallbacks for example):

{{ svg_icon(['brands/'.$item["brand_icon"],'light/thumbtack','solid/thumbtack'])->class('icon sm') }}

config.blade-svg

    /*
    |--------------------------------------------------------------------------
    | Fallback Filename (not extension)
    |--------------------------------------------------------------------------
    |
    | If the specified svg file does not exist then it will fallback to this file...
    |
    */

    'svg_default_name' => 'fallback',

SvgFactory


public function svgDefaultName()
    {  
        return $this->config->get('svg_default_name', '');
    }

public function getSvg($names)
    {
        $names = (array) $names;
        $names[] = $this->svgDefaultName();
        $name = $names[0];
        
        return $this->svgCache->get($name, function () use ( $names) {
            
            foreach($names as $fallback){
                $path = sprintf('%s/%s.svg', rtrim($this->svgPath()), str_replace('.', '/', $fallback));
                if ($this->files->exists($path))
                {
                    $name = $fallback;
                    return $this->svgCache[$name] = trim($this->files->get(sprintf('%s/%s.svg', rtrim($this->svgPath()), str_replace('.', '/', $name))));
                }
            }

        });
    }

Default classes for 3rd party icon packages

Would it be possible to provide default classes for icons provided by packages? For example, when I want to use brunocfalcao/blade-feather-icons, and want to set the default class in the config/blade-icons.php like this:

'feathericons' => [
    'class' => 'w-10 h-10'
]

It seems to override the set provided by the package, so I get the error:

Undefined index: path

The use case would be that I'm using different sets and packages for different purposes, and I would avoid repetition if I could set the default size.

Support for viewBox sizing

Is there a way to specify the size of the SVG viewBox or otherwise size the SVG? For example, I'm using a set of SVG files from https://useiconic.com/open and I'd like to resize them.

Perhaps I'd just do:

@svg('people', ['width' => '15', 'height' => '15']) ?

ViewException with Blade components

Hi,

I'm testing the next-version branch, and I can't figure out how to use the Blade components.

Environment:

  • Laravel version: 7.12.0
  • PHP version: 7.4.3
  • No config cache

My blade-icons.php config file:

return [
    'sets' => [
        'default' => [
            'path' => 'resources/svg',
            'prefix' => 'icon',
            'class' => '',
        ],
    ],
    'class' => '',
];

I have an account.svg inside of resources/svg.

@svg('account') {{-- renders correctly --}}

{{ svg('account') }} {{-- renders correctly --}}

<x-icon-account/>

{{--

Facade\Ignition\Exceptions\ViewException
Unable to locate a class or view for component [icon-account].

--}}

Am I missing something ?

Question: How to provide fallback to @svg?

Hello,

How can I set a fallback to @svg if it can't find the specified icon?

This is what I did:

@php
  if (!file_exists(base_path(config('blade-svg.svg_path')).$item['icone'])) {
    $item['icone'] = 'icon-circle';
  }
@endphp

File does not exist at path

Thanks for this directive! and I only want to inline svgs :D

so I follow all the steps, I add the svg here:
image

and I'm using it like:
@svg('search', 'test-icon')

but I get this error..

File does not exist at path /Users/x1c0/projects/laravel/search.svg
(View: /Users/x1c0/projects/laravel/resources/views/layout/header.blade.php)

thanks for any help in advance!

Default attributes

I can add default classes in the config, but what about default attributes?

At the moment I'm having to type out the same attributes each time, eg:

@svg('my-icon', 'text-red', ['aria-hidden' => 'true', 'viewBox' => '0 0 24 24'])

Spritesheet / symbol

@adamwathan: I want to inline the same (quite complex) SVG multiple times on a page so
I can style it differently using page CSS.
Despite gzip I think using a symbol for referencing to the same inlined SVG would be the best approach.
Can I do this with blade-svg? I want to prevent duplicate SVG markup.

Nested filepaths possible?

Just a quick question since I am getting File does not exist-errors when trying to use the @svg-directive like this:

@svg('icons/cards/info-blue')

Do all the files have to sit in the same directory or is there any way I can use nested / multi-level paths?

Many thanks for your efforts with Blade SVG, very much appreciated!

Add install to readme and fix composer file.

Hey @adamwathan currently I can not install this package via composer.

That might have to do with this part in the composer file:

 "name": "nothingworks/blade-svg",

Can you maybe make it available and add a line to the readme once it works, so one can just copy it to the cli? Thanks.

Class attribute gets overridden instead of appended

  • Library Version: 0.4.0
  • Laravel Version: 7.17.2
  • PHP Version: 7.4.6 @ Ubuntu 18.04 WSL2

Description:

When adding a custom class, the default classes are not added anymore.
Note that this worked perfectly in the preview build you had previously @ Adam's blade-svg.

Readme says:
You can also pass classes to your icon components (default classes will be applied as well):
<x-icon-camera class="icon-lg"/>

Steps To Reproduce:

<x-icon-calendar-lock />
returns:
<svg class="icon sl-micro" ... >...</svg>

but,
<x-icon-calendar-lock class="text-orange-400" />
returns:
<svg class="text-orange-400" ... >...</svg>

What I expected:
<svg class="icon sl-micro text-orange-400" ... >...</svg>

Partial content of resources/svg/icon/streamline-micro/calendar-lock.svg (!; licensing):

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.com/svgjs" viewBox="0 0 10 10">
  <g>
    <path .... />
  </g>
</svg>

My Config (blade-icons.php)

<?php
return [
    'sets' => [
        'streamline-micro' => [
            'path' => 'resources/svg/icon/streamline-micro',
            'prefix' => 'icon', // 'icon-sl-micro',
            'class' => 'sl-micro'
        ],

        'streamline-light' => [
            'path' => 'resources/svg/icon/streamline-light',
            'prefix' => 'icon-sl-light',
            'class' => 'sl-light'
        ],

    ],
    'class' => 'icon',
];

SVG with style tag + Vue

Hi,

I am wondering if I am going about this the wrong way.

I have SVGs with embedded styles (<style>...</style>) but I cannot use them if I am including them inside a Vue app as Vue will complain:
Templates should only be responsible for mapping the state to the UI. Avoid placing tags with side-effects in your templates, such as <style>, as they will not be parsed.

I have found the way to counter this would be to change the <style> tags to <svg:style> inside my SVGs. However, the following function will place my given SVG class in both elements:
https://github.com/adamwathan/blade-svg/blob/600269d60efe52bf9fc2cc610b21744cd69425df/src/Svg.php#L55-L62

Shouldn't the function return :
return \Illuminate\Support\Str::replaceFirst('<svg', '<svg ' . $this->renderAttributes(), $this->factory->getSvg($this->imageName));
?

Or maybe I am doing it wrong.

Thanks.

Default size to prevent full screen svgs when using svg icons

Rendered svg icons might benefit from having a default fallback size to prevent them taking the entire screen if stylesheet with .icon definition is blocked or takes time to load.

Not sure how it would work though. Maybe a recommendation to add e.g.

<style>
.icon { height: 1em; }
</style>

directly in html template? 🙂

Prevent adding class if not specified a class

If the svg itself has the class attribute already. svg_image('Foo') will overwrite the original class attribute with an empty value.

Thinking of a svg that can be used at multiple places, I have to specify the class name every time, which means it's hard to change when I want to change the class name of the svg, because I have to change all the args of the svg_image one by one.

Add auto discover for Laravel and allow absolute paths

Thank you Adam for this useful package!
I started using it and I noticed it doesn't allow absolute paths for the svg_path option for example like most other packages do. I wanted to use the public_path() or storage_path() helper to define the path.
A nice bonus would be having the auto discovery functionality from Laravel too.
Would you also accept a PR for such changes?

`alt` attribute not in SVG spec for alternative text.

Not in SVG spec nor SVG2 spec too.

What matches with alt for SVG is the <title> tag as a child of the <svg> tag.

So, this:

    @icon('cog', 'icon-lg', ['alt' => 'Gear icon']) Settings

should render as:

    <svg class="icon icon-lg">
        <title>Gear icon</title>
        <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#zondicon-cog"></use>
    </svg>

instead of:

    <svg class="icon icon-lg" alt="Gear icon">
        <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#zondicon-cog"></use>
    </svg>

There’s more resource about VG accessibility in this Gist by @davidhund and in the comments. Haven’t read it yet.

I’m not familiar with issues and pull requests, but if I dig into it, I'll make one to contribute.

failed to open stream

Don't work save sprite, failed to open stream: No such file or directory
'spritesheet_path' => 'resources/assets/svg/spritesheet.svg', //not found and not create =(

How do you pass this to a variable?

I'm using a variable placeholder for the icon, but it obviously renders as a string. How can I get it to execute properly?

@php $svg = '' @endphp

@if($service == 'Facebook')
@php $svg = "@svg('facebook', 'icon-facebook')" @endphp
@elseif($service == 'Twitter')
@php $svg = "@svg('twitter', 'icon-twitter')" @endphp
@endif

<li>
<a target="_blank" rel="noopener noreferrer" href={!! $url !!}><span class="sr-only">{!! $service !!}</span>{!! $svg !!}</a>
</li>

Alter when config gets set to allow for Middleware

It looks like the config that is used in the package gets locked in during the register method of the ServiceProvider. I would like to alter the svg_path in my Middleware to allow for different locations for different tenants but since it is set in the ServiceProvider any changes I make to it in my Middleware are disregarded.

Overriding the "default" set in svg helper

The helper (and incidentally the blade directive) don't seem to be able to see another icon set than default.

Proposition:

  • Add the ability to override the default set key.

  • Make a way to prefix in the first parameter of svg($name) which set to actually look in, overriding default.
    eg. @svg('other-set.subfolder.filename', ...)

If this is already possible; I might be missing documentation on how to force a certain set to be used in this helper.

Add markup into SVG

Is it possible to add markup in a SVG body, like blade components?

@svg('some.svg')
Extra markup that goes into SVG.
@endsvg

Provide more accessibility helpers

Accordingly
https://www.deque.com/blog/creating-accessible-svgs/
https://css-tricks.com/accessible-svgs/

We need a simple way to add default "aria-hidden='true'" attribute when icons used just like icons near descriptive texts
And ability to set descriptive title and text inside a svg tag if we need to add some description
for ex.

<x-icon-o-bell  "role"="image">
   <title>Notificatons</title>
</x-icon-o-bell>

or

@svg('heroicon-o-bell', ['class'=>'w-8 h-8', 'role'=>'image', 'a11y-title'=>'Notifications', 'a11y-desc'=>'Show recent notification list'])

Use dot notation in the directive

I have a project that has a ton of svg's. So I put them in svg/{pagename}/*.

In normal Laravel fashion, I'd assume something like this would work: @icon('pricing.ic-api') but it fails. You have to fall back to the slash @icon('pricing/ic-api')

You should fix this so I can sleep well this weekend, which always to be my birthday weekend. No pressure, but I think you'd feel bad if I didn't sleep for 48 hours and then was angry with my family.

Think of the children Adam!

Blade SVG on sharing host not render

On sharing host, the blade Svg doesn't render, i don't know if it does not allow me to run artisan on terminal, php artisan vendor:publish --provider="BladeSvg\BladeSvgServiceProvider" , so i created my copy the config file from my localhost. Then the bladesvg didn't render.

Document usage in Vue

Hi guys,

After some fiddling and reading these links https://calebporzio.com/using-inline-svgs-in-vue-compoments/ and https://laravel-mix.com/extensions/vue-svgicon I thought it could be easier if you just import the generated HTML into you component.

In blade view:

@php
$svgIcon = svg_image('cog', 'icon icon-lg');
@endphp

<product icon="{{$svgIcon->renderInline() }} "></product>

Please note the missing : before icon.

In Vue:

<template>
    <div v-html="icon"></div>
</template>

 export default {
        props: ['icon'],
}

Is it an idea to document this approach for Vue in the readme?

Possibility to call spritesheet as param of "svg_spritesheet"

Hi. I usually have different layouts and different icon collections in my projects. Different landing pages use different icon sets.

The way blade-svg package works does not allow the usage of multiple svg spritesheets, so you would need to render icons you are not actually going to use in every page (maybe I am wrong).

I think it would be very convenient if we could pass the location of any sprite sheet from any view, being able to switch icon collections as desired. Sometimes you need a collection of only three icons, for example. It would be nice if we could create and render a spritesheet for only those three icons instead of a big set of svg's.

Thanks in advance.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.