Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

set based disk #76

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions config/blade-icons.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@
// */
//
// 'path' => 'resources/svg',

// /*
// |-----------------------------------------------------------------
// | Icons disk
// |-----------------------------------------------------------------
// |
// | Provide disk where placed SVG icons. Icons are loaded recursively
// | so there's no need to list every sub-directory.
// |
// */
//
// 'path' => 'resources/svg',
davitbek marked this conversation as resolved.
Show resolved Hide resolved
//
// /*
// |--------------------------------------------------------------------------
Expand Down
5 changes: 3 additions & 2 deletions src/BladeIconsServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ private function registerFactory(): void
$factory = new Factory(new Filesystem(), $config['class'] ?? '');

foreach ($config['sets'] ?? [] as $set => $options) {
$options['path'] = $app->basePath($options['path']);

if (! empty($options['path'])) {
$options['path'] = $app->basePath($options['path']);
}
$factory->add($set, $options);
}

Expand Down
5 changes: 5 additions & 0 deletions src/Exceptions/CannotRegisterIconSet.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ public static function pathNotDefined(string $set): self
return new static("The options for the \"$set\" set don't have a path defined.");
}

public static function pathOrDiskNotDefined(string $set): self
{
return new static("The options for the \"$set\" set don't have a path or disk defined.");
davitbek marked this conversation as resolved.
Show resolved Hide resolved
}

public static function nonExistingPath(string $set, string $path): self
{
return new static("The [$path] path for the \"$set\" set does not exist.");
Expand Down
58 changes: 46 additions & 12 deletions src/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Illuminate\Contracts\Filesystem\FileNotFoundException;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;

final class Factory
Expand Down Expand Up @@ -42,8 +43,8 @@ public function all(): array
*/
public function add(string $set, array $options): self
{
if (! isset($options['path'])) {
throw CannotRegisterIconSet::pathNotDefined($set);
if (! isset($options['path']) && !isset($options['disk'])) {
throw CannotRegisterIconSet::pathOrDiskNotDefined($set);
}

if (! isset($options['prefix'])) {
Expand All @@ -54,7 +55,7 @@ public function add(string $set, array $options): self
throw CannotRegisterIconSet::prefixNotUnique($set, $collidingSet);
}

if ($this->filesystem->missing($options['path'])) {
if (isset($options['path']) && $this->filesystem->missing($options['path'])) {
throw CannotRegisterIconSet::nonExistingPath($set, $options['path']);
}

Expand All @@ -68,18 +69,43 @@ public function add(string $set, array $options): self
public function registerComponents(): void
{
foreach ($this->sets as $set) {
foreach ($this->filesystem->allFiles($set['path']) as $file) {
$path = array_filter(explode('/', Str::after($file->getPath(), $set['path'])));

Blade::component(
SvgComponent::class,
implode('.', array_filter($path + [$file->getFilenameWithoutExtension()])),
$set['prefix']
);
if (isset($set['path'])) {
$this->registerComponentsByPath($set);
} else {
$this->registerComponentsByDisk($set);
davitbek marked this conversation as resolved.
Show resolved Hide resolved
}
}
}

protected function registerComponentsByPath($set) : void
{
foreach ($this->filesystem->allFiles($set['path']) as $file) {
$relativePath = Str::after($file->getPath(), $set['path']);
$relativePath = str_replace(DIRECTORY_SEPARATOR, '/', $relativePath);
davitbek marked this conversation as resolved.
Show resolved Hide resolved
$path = array_filter(explode('/', $relativePath));
Blade::component(
SvgComponent::class,
implode('.', array_filter($path + [$file->getFilenameWithoutExtension()])),
$set['prefix']
);
}
}

protected function registerComponentsByDisk($set) : void
{
$allFiles = Storage::disk($set['disk'])->allFiles();
foreach ($allFiles as $file) {
$file = str_replace('/', '.', $file);
$path = pathinfo($file, PATHINFO_FILENAME);

Blade::component(
SvgComponent::class,
$path,
$set['prefix']
);
davitbek marked this conversation as resolved.
Show resolved Hide resolved
}
}

/**
* @throws SvgNotFound
*/
Expand All @@ -101,7 +127,9 @@ private function contents(string $set, string $name): string

if (isset($this->sets[$set])) {
try {
return $this->cache[$set][$name] = $this->getSvgFromPath($name, $this->sets[$set]['path']);
return $this->cache[$set][$name] = isset($this->sets[$set]['path'])
? $this->getSvgFromPath($name, $this->sets[$set]['path'])
: $this->getSvgFromDisk($name, $this->sets[$set]['disk']);
} catch (FileNotFoundException $exception) {
//
}
Expand All @@ -119,6 +147,12 @@ private function getSvgFromPath(string $name, string $path): string
)));
}

private function getSvgFromDisk(string $name, string $disk): string
{
$path = str_replace('.', DIRECTORY_SEPARATOR, $name) . '.svg';
return Storage::disk($disk)->get($path);
davitbek marked this conversation as resolved.
Show resolved Hide resolved
}

private function splitSetAndName(string $name): array
{
$prefix = Str::before($name, '-');
Expand Down
86 changes: 86 additions & 0 deletions tests/ComponentsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ public function components_are_registered_with_their_subdirectories()
'icon-solid.camera' => Svg::class,
'icon-zondicon-flag' => Svg::class,
'zondicon-flag' => Svg::class,
'disk-camera' => Svg::class,
'disk-solid.camera' => Svg::class,
], Blade::getClassComponentAliases());
}

Expand All @@ -43,6 +45,23 @@ public function it_can_render_an_icon()
$this->assertSame($expected, $compiled);
}

/** @test */
public function it_can_render_an_icon_by_disk()
{
$this->prepareSets();

$compiled = $this->renderView('disk/icon');

$expected = <<<HTML
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor">
<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>
HTML;

$this->assertSame($expected, $compiled);
}

/** @test */
public function it_can_render_an_icon_with_default_classes()
{
Expand All @@ -60,6 +79,23 @@ public function it_can_render_an_icon_with_default_classes()
$this->assertSame($expected, $compiled);
}

/** @test */
public function it_can_render_an_icon_with_default_classes_by_disk()
{
$this->prepareSets('', ['disk' => 'w-6 h-6']);

$compiled = $this->renderView('disk/icon');

$expected = <<<HTML
<svg class="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<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>
HTML;

$this->assertSame($expected, $compiled);
}

/** @test */
public function it_can_render_an_icon_with_default_classes_and_added_classes()
{
Expand All @@ -77,6 +113,23 @@ public function it_can_render_an_icon_with_default_classes_and_added_classes()
$this->assertSame($expected, $compiled);
}

/** @test */
public function it_can_render_an_icon_with_default_classes_and_added_classes_by_disk()
{
$this->prepareSets('text-blue-500', ['disk' => 'w-6 h-6']);

$compiled = $this->renderView('disk/icon-with-attributes');

$expected = <<<HTML
<svg data-foo="1" class="text-blue-500 w-6 h-6 icon icon-lg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<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>
HTML;

$this->assertSame($expected, $compiled);
}

/** @test */
public function it_can_render_an_icon_from_a_subdirectory()
{
Expand All @@ -93,6 +146,22 @@ public function it_can_render_an_icon_from_a_subdirectory()
$this->assertSame($expected, $compiled);
}

/** @test */
public function it_can_render_an_icon_from_a_subdirectory_by_disk()
{
$this->prepareSets();

$compiled = $this->renderView('disk/icon-subdirectory');

$expected = <<<HTML
<svg viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M4 5a2 2 0 00-2 2v8a2 2 0 002 2h12a2 2 0 002-2V7a2 2 0 00-2-2h-1.586a1 1 0 01-.707-.293l-1.121-1.121A2 2 0 0011.172 3H8.828a2 2 0 00-1.414.586L6.293 4.707A1 1 0 015.586 5H4zm6 9a3 3 0 100-6 3 3 0 000 6z" clip-rule="evenodd"/>
</svg>
HTML;

$this->assertSame($expected, $compiled);
}

/** @test */
public function it_can_render_an_icon_from_a_specific_set()
{
Expand Down Expand Up @@ -124,6 +193,23 @@ public function it_can_render_attributes()
$this->assertSame($expected, $compiled);
}

/** @test */
public function it_can_render_attributes_by_disk()
{
$this->prepareSets();

$compiled = $this->renderView('disk/icon-with-attributes');

$expected = <<<HTML
<svg data-foo="1" class="icon icon-lg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<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>
HTML;

$this->assertSame($expected, $compiled);
}

private function renderView(string $view): string
{
return trim(View::file(__DIR__ . "/resources/views/{$view}.blade.php")->render());
Expand Down
2 changes: 1 addition & 1 deletion tests/FactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public function it_can_add_a_set()

$sets = $factory->all();

$this->assertCount(2, $sets);
$this->assertCount(3, $sets);
}

/** @test */
Expand Down
11 changes: 11 additions & 0 deletions tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ abstract class TestCase extends OrchestraTestCase
{
protected function prepareSets(string $defaultClass = '', array $setClasses = []): Factory
{
$disks = config('filesystems.disks');
$disks['svg'] = [
'driver' => 'local',
'root' => __DIR__ . '/resources/disk-svg',
];
config(['filesystems.disks' => $disks]);

$factory = (new Factory(new Filesystem(), $defaultClass))
->add('default', [
'path' => __DIR__ . '/resources/svg',
Expand All @@ -23,6 +30,10 @@ protected function prepareSets(string $defaultClass = '', array $setClasses = []
'path' => __DIR__ . '/resources/zondicons',
'prefix' => 'zondicon',
'class' => $setClasses['zondicons'] ?? '',
])->add('disk', [
'disk' => 'svg',
'prefix' => 'disk',
'class' => $setClasses['disk'] ?? '',
]);

return $this->app->instance(Factory::class, $factory);
Expand Down
4 changes: 4 additions & 0 deletions tests/resources/disk-svg/camera.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions tests/resources/disk-svg/solid/camera.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions tests/resources/views/disk/icon-subdirectory.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<x-disk-solid.camera/>
1 change: 1 addition & 0 deletions tests/resources/views/disk/icon-with-attributes.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<x-disk-camera class="icon icon-lg" data-foo/>
1 change: 1 addition & 0 deletions tests/resources/views/disk/icon.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<x-disk-camera/>