多🌹444收拾收拾计算机视觉手机手机手机手机4大尺寸惆怅长岑长 ??????????????????????????С??????????????P??????????????????????????????????????????????????????^?????????? ????j?????????? ? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!blade-icons/pint.json000064400000000165152665540470010611 0ustar00{ "notPath": [ "tests/fixtures/blade-icons.php", "tests/fixtures/generated-manifest.php" ] } blade-icons/src/Generation/IconGenerator.php000064400000004776152665540470015112 0ustar00filesystem = new Filesystem; $this->sets = $sets; } public static function create(array $config): self { return new self($config); } public function generate(): void { foreach ($this->sets as $set) { $destination = $this->getDestinationDirectory($set); $files = array_filter( $this->filesystem->files($set['source']), fn (SplFileInfo $value) => str_ends_with($value->getFilename(), '.svg') ); foreach ($files as $file) { $filename = Str::of($file->getFilename()); $filename = $this->applyPrefixes($set, $filename); $filename = $this->applySuffixes($set, $filename); $pathname = $destination.$filename; $this->filesystem->copy($file->getRealPath(), $pathname); if (is_callable($set['after'] ?? null)) { $set['after']($pathname, $set, $file); } } } } private function getDestinationDirectory(array $set): string { $destination = Str::finish($set['destination'], DIRECTORY_SEPARATOR); if (! Arr::get($set, 'safe', false)) { $this->filesystem->deleteDirectory($destination); } $this->filesystem->ensureDirectoryExists($destination); return $destination; } private function applyPrefixes($set, Stringable $filename): Stringable { if ($set['input-prefix'] ?? false) { $filename = $filename->after($set['input-prefix']); } if ($set['output-prefix'] ?? false) { $filename = $filename->prepend($set['output-prefix']); } return $filename; } private function applySuffixes($set, Stringable $filename): Stringable { if ($set['input-suffix'] ?? false) { $filename = $filename->replace($set['input-suffix'].'.svg', '.svg'); } if ($set['output-suffix'] ?? false) { $filename = $filename->replace('.svg', $set['output-suffix'].'.svg'); } return $filename; } } blade-icons/src/Factory.php000064400000016411152665540470011654 0ustar00filesystem = $filesystem; $this->manifest = $manifest; $this->disks = $disks; $this->config = $config; $this->config['class'] = $config['class'] ?? ''; $this->config['attributes'] = (array) ($config['attributes'] ?? []); $this->config['fallback'] = $config['fallback'] ?? ''; $this->config['components'] = [ 'disabled' => $config['components']['disabled'] ?? false, 'default' => $config['components']['default'] ?? 'icon', ]; } /** * @internal This method is only meant for internal purposes and does not fall under the package's BC promise. */ public function all(): array { return $this->sets; } /** * @throws CannotRegisterIconSet */ public function add(string $set, array $options): self { if (! isset($options['prefix'])) { throw CannotRegisterIconSet::prefixNotDefined($set); } if ($collidingSet = $this->getSetByPrefix($options['prefix'])) { throw CannotRegisterIconSet::prefixNotUnique($set, $collidingSet); } $paths = (array) ($options['paths'] ?? $options['path'] ?? []); $options['paths'] = array_filter(array_map( fn ($path) => $path !== '/' ? rtrim($path, '/') : $path, $paths, )); if (empty($options['paths'])) { throw CannotRegisterIconSet::pathsNotDefined($set); } unset($options['path']); $filesystem = $this->filesystem($options['disk'] ?? null); foreach ($options['paths'] as $path) { if ($path !== '/' && $filesystem->missing($path)) { throw CannotRegisterIconSet::nonExistingPath($set, $path); } } $this->sets[$set] = $options; $this->cache = []; return $this; } public function registerComponents(): void { if ($this->config['components']['disabled']) { return; } foreach ($this->manifest->getManifest($this->sets) as $set => $paths) { foreach ($paths as $icons) { foreach ($icons as $icon) { Blade::component( SvgComponent::class, $icon, $this->sets[$set]['prefix'] ?? '', ); } } } } /** * @throws SvgNotFound */ public function svg(string $name, $class = '', array $attributes = []): Svg { [$set, $name] = $this->splitSetAndName($name); try { return new Svg( $name, $this->contents($set, $name), $this->formatAttributes($set, $class, $attributes), ); } catch (SvgNotFound $exception) { if (isset($this->sets[$set]['fallback']) && $this->sets[$set]['fallback'] !== '') { $name = $this->sets[$set]['fallback']; try { return new Svg( $name, $this->contents($set, $name), $this->formatAttributes($set, $class, $attributes), ); } catch (SvgNotFound $exception) { // } } if ($this->config['fallback']) { return $this->svg($this->config['fallback'], $class, $attributes); } throw $exception; } } /** * @throws SvgNotFound */ private function contents(string $set, string $name): string { if (isset($this->cache[$set][$name])) { return $this->cache[$set][$name]; } if (isset($this->sets[$set])) { foreach ($this->sets[$set]['paths'] as $path) { try { return $this->cache[$set][$name] = $this->getSvgFromPath( $name, $path, $this->sets[$set]['disk'] ?? null, ); } catch (FileNotFoundException $exception) { // } } } throw SvgNotFound::missing($set, $name); } private function getSvgFromPath(string $name, string $path, ?string $disk = null): string { $contents = trim($this->filesystem($disk)->get(sprintf( '%s/%s.svg', rtrim($path), str_replace('.', '/', $name), ))); return $this->cleanSvgContents($contents); } private function cleanSvgContents(string $contents): string { return trim(preg_replace('/^(<\?xml.+?\?>)/', '', $contents)); } private function splitSetAndName(string $name): array { $prefix = Str::before($name, '-'); $set = $this->getSetByPrefix($prefix); $name = $set ? Str::after($name, '-') : $name; return [$set ?? 'default', $name]; } private function getSetByPrefix(string $prefix): ?string { return collect($this->sets)->where('prefix', $prefix)->keys()->first(); } private function formatAttributes(string $set, $class = '', array $attributes = []): array { if (is_string($class)) { if ($class = $this->buildClass($set, $class)) { $attributes['class'] = $attributes['class'] ?? $class; } } elseif (is_array($class)) { $attributes = $class; if (! isset($attributes['class']) && $class = $this->buildClass($set, '')) { $attributes['class'] = $class; } } $attributes = array_merge( $this->config['attributes'], (array) ($this->sets[$set]['attributes'] ?? []), $attributes, ); foreach ($attributes as $key => $value) { if (is_string($value)) { $attributes[$key] = str_replace('"', '"', $value); } } return $attributes; } private function buildClass(string $set, string $class): string { return trim(sprintf( '%s %s', trim(sprintf('%s %s', $this->config['class'], $this->sets[$set]['class'] ?? '')), $class, )); } /** * @return \Illuminate\Contracts\Filesystem\Filesystem|Filesystem */ private function filesystem(?string $disk = null) { return $this->disks && $disk ? $this->disks->disk($disk) : $this->filesystem; } } blade-icons/src/Exceptions/SvgNotFound.php000064400000000443152665540470014600 0ustar00filesystem = $filesystem; $this->manifestPath = $manifestPath; $this->disks = $disks; } private function build(array $sets): array { $compiled = []; foreach ($sets as $name => $set) { $icons = []; foreach ($set['paths'] as $path) { $icons[$path] = []; foreach ($this->filesystem($set['disk'] ?? null)->allFiles($path) as $file) { if ($file instanceof SplFileInfo) { if ($file->getExtension() !== 'svg') { continue; } $icons[$path][] = $this->format($file->getPathName(), $path); } else { if (! Str::endsWith($file, '.svg')) { continue; } $icons[$path][] = $this->format($file, $path); } } $icons[$path] = array_unique($icons[$path]); } $compiled[$name] = array_filter($icons); } return $compiled; } /** * @return \Illuminate\Contracts\Filesystem\Filesystem|Filesystem */ private function filesystem(?string $disk = null) { return $this->disks && $disk ? $this->disks->disk($disk) : $this->filesystem; } public function delete(): bool { return $this->filesystem->delete($this->manifestPath); } private function format(string $pathname, string $path): string { return (string) Str::of($pathname) ->after($path.DIRECTORY_SEPARATOR) ->replace(DIRECTORY_SEPARATOR, '.') ->basename('.svg'); } public function getManifest(array $sets): array { if (! is_null($this->manifest)) { return $this->manifest; } if (! $this->filesystem->exists($this->manifestPath)) { return $this->manifest = $this->build($sets); } return $this->manifest = $this->filesystem->getRequire($this->manifestPath); } /** * @throws Exception */ public function write(array $sets): void { if (! is_writable($dirname = dirname($this->manifestPath))) { throw new Exception("The {$dirname} directory must be present and writable."); } $this->filesystem->replace( $this->manifestPath, 'build($sets), true).';', ); } } blade-icons/src/Components/Svg.php000064400000000766152665540470013137 0ustar00getIterator()->getArrayCopy(); $class = $attributes['class'] ?? ''; unset($attributes['class']); return svg($this->componentName, $class, $attributes)->toHtml(); }; } } blade-icons/src/Components/Icon.php000064400000001140152665540470013253 0ustar00name = $name; } public function render(): Closure { return function (array $data) { $attributes = $data['attributes']->getIterator()->getArrayCopy(); $class = $attributes['class'] ?? ''; unset($attributes['class']); return svg($this->name, $class, $attributes)->toHtml(); }; } } blade-icons/src/Svg.php000064400000005413152665540470011004 0ustar00name = $name; $this->contents = $this->deferContent($contents, $attributes['defer'] ?? false); unset($attributes['defer']); $this->attributes = $attributes; } public function name(): string { return $this->name; } public function contents(): string { return $this->contents; } /** * This method adds a title element and an aria-labelledby attribute to the SVG. * To comply with accessibility standards, SVGs should have a title element. * Check accessibility patterns for icons: https://www.deque.com/blog/creating-accessible-svgs/ */ public function addTitle(string $title): string { // create title element $titleElement = ''.$title.''; // add role attribute to svg element $this->attributes['role'] = 'img'; // add title element to svg return preg_replace('/]*>/', "$0$titleElement", $this->contents); } public function toHtml(): string { // Check if the title attribute is set and add a title element to the SVG if (array_key_exists('title', $this->attributes)) { $this->contents = $this->addTitle($this->attributes['title']); } return str_replace( 'renderAttributes()), $this->contents, ); } protected function deferContent(string $contents, $defer = false): string { if ($defer === false) { return $contents; } $svgContent = Str::of($contents) ->replaceMatches('/]*>/', '') ->replaceMatches('/<\/svg>/', '') ->__toString(); // Force Unix line endings for hash. $hashContent = str_replace(PHP_EOL, "\n", $svgContent); $hash = 'icon-'.(is_string($defer) ? $defer : md5($hashContent)); $contents = str_replace($svgContent, strtr('', [':href' => '#'.$hash]), $contents).PHP_EOL; $svgContent = ltrim($svgContent, PHP_EOL); $contents .= << {$svgContent} @endpush @endonce BLADE; return $contents; } } blade-icons/src/Concerns/RendersAttributes.php000064400000001660152665540470015470 0ustar00attributes; } private function renderAttributes(): string { if (count($this->attributes) == 0) { return ''; } return ' '.collect($this->attributes)->map(function (string $value, $attribute) { if (is_int($attribute)) { return $value; } return sprintf('%s="%s"', $attribute, $value); })->implode(' '); } public function __call(string $method, array $arguments): self { if (count($arguments) === 0) { $this->attributes[] = Str::snake($method, '-'); } else { $this->attributes[Str::snake($method, '-')] = $arguments[0]; } return $this; } } blade-icons/src/BladeIconsServiceProvider.php000064400000006714152665540470015311 0ustar00registerConfig(); $this->registerFactory(); $this->registerManifest(); } public function boot(): void { $this->bootCommands(); $this->bootDirectives(); $this->bootIconComponent(); $this->bootPublishing(); } private function registerConfig(): void { $this->mergeConfigFrom(__DIR__.'/../config/blade-icons.php', 'blade-icons'); } private function registerFactory(): void { $this->app->singleton(Factory::class, function (Application $app) { $config = $app->make('config')->get('blade-icons', []); $factory = new Factory( new Filesystem, $app->make(IconsManifest::class), $app->make(FilesystemFactory::class), $config, ); foreach ($config['sets'] ?? [] as $set => $options) { if (! isset($options['disk']) || ! $options['disk']) { $paths = $options['paths'] ?? $options['path'] ?? []; $options['paths'] = array_map( fn ($path) => $app->basePath($path), (array) $paths, ); } $factory->add($set, $options); } return $factory; }); $this->callAfterResolving(ViewFactory::class, function ($view, Application $app) { $app->make(Factory::class)->registerComponents(); }); } private function registerManifest(): void { $this->app->singleton(IconsManifest::class, function (Application $app) { return new IconsManifest( new Filesystem, $this->manifestPath(), $app->make(FilesystemFactory::class), ); }); } private function manifestPath(): string { return $this->app->bootstrapPath('cache/blade-icons.php'); } private function bootCommands(): void { if ($this->app->runningInConsole()) { $this->commands([ Console\CacheCommand::class, Console\ClearCommand::class, ]); if (method_exists($this, 'optimizes')) { $this->optimizes( 'icons:cache', 'icons:clear', 'blade-icons' ); } } } private function bootDirectives(): void { Blade::directive('svg', fn ($expression) => ""); } private function bootIconComponent(): void { if ($name = config('blade-icons.components.default')) { Blade::component($name, Icon::class); } } private function bootPublishing(): void { if ($this->app->runningInConsole()) { $this->publishes([ __DIR__.'/../config/blade-icons.php' => $this->app->configPath('blade-icons.php'), ], 'blade-icons'); } } } blade-icons/src/helpers.php000064400000000420152665540470011700 0ustar00svg($name, $class, $attributes); } } blade-icons/src/Console/CacheCommand.php000064400000001333152665540470014146 0ustar00write($factory->all()); $this->info('Blade icons manifest file generated successfully!'); return 0; } } blade-icons/src/Console/ClearCommand.php000064400000001206152665540470014170 0ustar00delete(); $this->info('Blade icons manifest file cleared!'); return 0; } } blade-icons/composer.json000064400000003607152665540470011472 0ustar00{ "name": "blade-ui-kit/blade-icons", "description": "A package to easily make use of icons in your Laravel Blade views.", "keywords": ["Blade", "Icons", "Laravel", "SVG"], "homepage": "https://github.com/blade-ui-kit/blade-icons", "license": "MIT", "support": { "issues": "https://github.com/blade-ui-kit/blade-icons/issues", "source": "https://github.com/blade-ui-kit/blade-icons" }, "authors": [ { "name": "Dries Vints", "homepage": "https://driesvints.com" } ], "funding": [ { "type": "github", "url": "https://github.com/sponsors/driesvints" }, { "type": "paypal", "url": "https://www.paypal.com/paypalme/driesvints" } ], "require": { "php": "^7.4|^8.0", "illuminate/contracts": "^8.0|^9.0|^10.0|^11.0|^12.0", "illuminate/filesystem": "^8.0|^9.0|^10.0|^11.0|^12.0", "illuminate/support": "^8.0|^9.0|^10.0|^11.0|^12.0", "illuminate/view": "^8.0|^9.0|^10.0|^11.0|^12.0", "symfony/console": "^5.3|^6.0|^7.0", "symfony/finder": "^5.3|^6.0|^7.0" }, "require-dev": { "mockery/mockery": "^1.5.1", "orchestra/testbench": "^6.0|^7.0|^8.0|^9.0|^10.0", "phpunit/phpunit": "^9.0|^10.5|^11.0" }, "bin": [ "bin/blade-icons-generate" ], "autoload": { "psr-4": { "BladeUI\\Icons\\": "src" }, "files": [ "src/helpers.php" ] }, "autoload-dev": { "psr-4": { "Tests\\": "tests" } }, "extra": { "laravel": { "providers": [ "BladeUI\\Icons\\BladeIconsServiceProvider" ] } }, "config": { "sort-packages": true }, "minimum-stability": "dev", "prefer-stable": true } blade-icons/bin/blade-icons-generate000064400000001343152665540470013406 0ustar00#!/usr/bin/env php setCode(function (InputInterface $input, OutputInterface $output) { $output->writeln("Starting to generate icons..."); IconGenerator::create( require getcwd().'/config/generation.php' )->generate(); $output->writeln("Finished generating icons!"); return Command::SUCCESS; })->run(); blade-icons/LICENSE.md000064400000002061152665540470010345 0ustar00The MIT License (MIT) Copyright (c) Dries Vints Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. blade-icons/config/blade-icons.php000064400000013535152665540470013107 0ustar00 [ // 'default' => [ // // /* // |----------------------------------------------------------------- // | Icons Path // |----------------------------------------------------------------- // | // | Provide the relative path from your app root to your SVG icons // | directory. Icons are loaded recursively so there's no need to // | list every sub-directory. // | // | Relative to the disk root when the disk option is set. // | // */ // // 'path' => 'resources/svg', // // /* // |----------------------------------------------------------------- // | Filesystem Disk // |----------------------------------------------------------------- // | // | Optionally, provide a specific filesystem disk to read // | icons from. When defining a disk, the "path" option // | starts relatively from the disk root. // | // */ // // 'disk' => '', // // /* // |----------------------------------------------------------------- // | Default Prefix // |----------------------------------------------------------------- // | // | This config option allows you to define a default prefix for // | your icons. The dash separator will be applied automatically // | to every icon name. It's required and needs to be unique. // | // */ // // 'prefix' => 'icon', // // /* // |----------------------------------------------------------------- // | Fallback Icon // |----------------------------------------------------------------- // | // | This config option allows you to define a fallback // | icon when an icon in this set cannot be found. // | // */ // // 'fallback' => '', // // /* // |----------------------------------------------------------------- // | Default Set Classes // |----------------------------------------------------------------- // | // | This config option allows you to define some classes which // | will be applied by default to all icons within this set. // | // */ // // 'class' => '', // // /* // |----------------------------------------------------------------- // | Default Set Attributes // |----------------------------------------------------------------- // | // | This config option allows you to define some attributes which // | will be applied by default to all icons within this set. // | // */ // // 'attributes' => [ // // 'width' => 50, // // 'height' => 50, // ], // // ], ], /* |-------------------------------------------------------------------------- | Global Default Classes |-------------------------------------------------------------------------- | | This config option allows you to define some classes which | will be applied by default to all icons. | */ 'class' => '', /* |-------------------------------------------------------------------------- | Global Default Attributes |-------------------------------------------------------------------------- | | This config option allows you to define some attributes which | will be applied by default to all icons. | */ 'attributes' => [ // 'width' => 50, // 'height' => 50, ], /* |-------------------------------------------------------------------------- | Global Fallback Icon |-------------------------------------------------------------------------- | | This config option allows you to define a global fallback | icon when an icon in any set cannot be found. It can | reference any icon from any configured set. | */ 'fallback' => '', /* |-------------------------------------------------------------------------- | Components |-------------------------------------------------------------------------- | | These config options allow you to define some | settings related to Blade Components. | */ 'components' => [ /* |---------------------------------------------------------------------- | Disable Components |---------------------------------------------------------------------- | | This config option allows you to disable Blade components | completely. It's useful to avoid performance problems | when working with large icon libraries. | */ 'disabled' => false, /* |---------------------------------------------------------------------- | Default Icon Component Name |---------------------------------------------------------------------- | | This config option allows you to define the name | for the default Icon class component. | */ 'default' => 'icon', ], ];