├── LICENSE.md ├── README.md ├── composer.json ├── pint.json ├── resources ├── dist │ └── badgeable-column.css └── views │ └── components │ └── badge.blade.php └── src ├── BadgeableColumnServiceProvider.php ├── Components ├── Badge.php ├── BadgeableColumn.php └── BadgeableEntry.php ├── Concerns └── HasBadges.php └── Enums └── BadgeSize.php /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) awcodes 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Filament Badgeable Column 2 | 3 | [![Latest Version on Packagist](https://img.shields.io/packagist/v/awcodes/filament-badgeable-column.svg?style=flat-square)](https://packagist.org/packages/awcodes/filament-badgeable-column) 4 | [![Total Downloads](https://img.shields.io/packagist/dt/awcodes/filament-badgeable-column.svg?style=flat-square)](https://packagist.org/packages/awcodes/filament-badgeable-column) 5 | 6 | ![badgeable-column-og](https://res.cloudinary.com/aw-codes/image/upload/w_1200,f_auto,q_auto/plugins/badgeable-column/awcodes-badgeable-column.jpg) 7 | 8 | With Filament Badgeable Column you prepend and append badges to your columns. 9 | 10 | ## Installation 11 | 12 | You can install the package via composer: 13 | 14 | ```bash 15 | composer require awcodes/filament-badgeable-column 16 | ``` 17 | 18 | In an effort to align with Filament's theming methodology you will need to use a custom theme to use this plugin. 19 | 20 | > **Note** 21 | > If you have not set up a custom theme and are using a Panel follow the instructions in the [Filament Docs](https://filamentphp.com/docs/3.x/panels/themes#creating-a-custom-theme) first. The following applies to both the Panels Package and the standalone Forms package. 22 | 23 | Add the plugin's views to your `tailwind.config.js` file. 24 | 25 | ```js 26 | content: [ 27 | '/awcodes/filament-badgeable-column/resources/**/*.blade.php', 28 | ] 29 | ``` 30 | 31 | ## Usage 32 | 33 | ```php 34 | use Awcodes\FilamentBadgeableColumn\Components\Badge; 35 | use Awcodes\FilamentBadgeableColumn\Components\BadgeableColumn; 36 | 37 | return $table 38 | ->columns([ 39 | BadgeableColumn::make('name') 40 | ->suffixBadges([ 41 | Badge::make('hot') 42 | ->label('Hot') 43 | ->color('danger') 44 | ->visible(fn(Model $record) => $record->qty < 5), 45 | ]) 46 | ->prefixBadges([ 47 | Badge::make('brand_name') 48 | ->label(fn(Model $record) => $record->status) 49 | ->color(function(Model $record) { 50 | return match ($record->status) { 51 | 'active' => 'success', 52 | 'inactive' => 'danger', 53 | default => 'warning', 54 | }; 55 | }) 56 | ]) 57 | ]); 58 | ``` 59 | 60 | You can also define the array of badges via a closure, if you want the array of badges to be based on dynamic data. The closure should return an array of `Badge` objects, similar to above. 61 | 62 | The example below assumes the records have a `BelongsToMany` relationship called `topics`, and shows how to display each topic name as a badge. 63 | 64 | ```php 65 | use Awcodes\FilamentBadgeableColumn\Components\Badge; 66 | use Awcodes\FilamentBadgeableColumn\Components\BadgeableColumn; 67 | 68 | return $table 69 | ->columns([ 70 | BadgeableColumn::make('title') 71 | ->suffixBadges(function($record) { 72 | return $record->topics->map(function($topic) { 73 | return Badge::make($topic->name)->color($topic->color); 74 | }); 75 | }) 76 | ->searchable() 77 | ->sortable(), 78 | ]); 79 | ``` 80 | 81 | ## Badgeable Tags Column 82 | 83 | > **Warning** 84 | > The Badgeable Tags Column has been deprecated please use the `TextColumn` `badge()` method instead. 85 | 86 | ## Badge Shape 87 | 88 | If you prefer to have a more "rounded" shape you can use the `asPills()` 89 | method to set the shape of the badges. 90 | 91 | ```php 92 | use Awcodes\FilamentBadgeableColumn\Components\Badge; 93 | use Awcodes\FilamentBadgeableColumn\Components\BadgeableColumn; 94 | 95 | return $table 96 | ->columns([ 97 | BadgeableColumn::make('name') 98 | ->asPills() 99 | ]); 100 | ``` 101 | 102 | ## Separator 103 | 104 | The default separator between the column text and the badges is '—'. 105 | If you would like to use a different separator, use the `separator()` 106 | method to set character to be used as a separator. 107 | 108 | ```php 109 | use Awcodes\FilamentBadgeableColumn\Components\Badge; 110 | use Awcodes\FilamentBadgeableColumn\Components\BadgeableColumn; 111 | 112 | return $table 113 | ->columns([ 114 | BadgeableColumn::make('name') 115 | ->separator(':') 116 | ]); 117 | ``` 118 | 119 | ## Changelog 120 | 121 | Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently. 122 | 123 | ## Contributing 124 | 125 | Please see [CONTRIBUTING](.github/CONTRIBUTING.md) for details. 126 | 127 | ## Security Vulnerabilities 128 | 129 | Please review [our security policy](../../security/policy) on how to report security vulnerabilities. 130 | 131 | ## Credits 132 | 133 | - [awcodes](https://github.com/awcodes) 134 | - [All Contributors](../../contributors) 135 | 136 | ## License 137 | 138 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information. 139 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "awcodes/filament-badgeable-column", 3 | "description": "Filament Tables column to append and prepend badges.", 4 | "keywords": [ 5 | "awcodes", 6 | "laravel", 7 | "filament", 8 | "filament-badgeable-column", 9 | "badger" 10 | ], 11 | "homepage": "https://github.com/awcodes/badger", 12 | "license": "MIT", 13 | "authors": [ 14 | { 15 | "name": "awcodes", 16 | "email": "awcodes1@gmail.com", 17 | "role": "Developer" 18 | } 19 | ], 20 | "require": { 21 | "php": "^8.1", 22 | "filament/filament": "^3.0", 23 | "spatie/laravel-package-tools": "^1.15" 24 | }, 25 | "require-dev": { 26 | "laravel/pint": "^1.0", 27 | "spatie/laravel-ray": "^1.26" 28 | }, 29 | "autoload": { 30 | "psr-4": { 31 | "Awcodes\\FilamentBadgeableColumn\\": "src" 32 | } 33 | }, 34 | "scripts": { 35 | "pint": "vendor/bin/pint" 36 | }, 37 | "config": { 38 | "sort-packages": true, 39 | "allow-plugins": { 40 | "composer/package-versions-deprecated": true, 41 | "pestphp/pest-plugin": true, 42 | "phpstan/extension-installer": true 43 | } 44 | }, 45 | "extra": { 46 | "laravel": { 47 | "providers": [ 48 | "Awcodes\\FilamentBadgeableColumn\\BadgeableColumnServiceProvider" 49 | ] 50 | } 51 | }, 52 | "minimum-stability": "dev", 53 | "prefer-stable": true 54 | } 55 | -------------------------------------------------------------------------------- /pint.json: -------------------------------------------------------------------------------- 1 | { 2 | "preset": "laravel", 3 | "rules": { 4 | "blank_line_before_statement": true, 5 | "concat_space": { 6 | "spacing": "one" 7 | }, 8 | "method_argument_space": true, 9 | "single_trait_insert_per_statement": true, 10 | "types_spaces": { 11 | "space": "single" 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /resources/dist/badgeable-column.css: -------------------------------------------------------------------------------- 1 | .badgeable-column-badge .truncate{overflow: visible !important;} 2 | -------------------------------------------------------------------------------- /resources/views/components/badge.blade.php: -------------------------------------------------------------------------------- 1 | @php 2 | use Awcodes\FilamentBadgeableColumn\Enums\BadgeSize; 3 | @endphp 4 | 5 | @if (! $isHidden()) 6 | @php 7 | $color = $getColor(); 8 | 9 | $size = match ($size = $getSize()) { 10 | BadgeSize::ExtraSmall, 'xs' => 'xs', 11 | BadgeSize::Small, 'sm', null => 'sm', 12 | BadgeSize::Medium, 'base', 'md' => 'md', 13 | default => $size, 14 | }; 15 | 16 | $badgeClasses = \Illuminate\Support\Arr::toCssClasses([ 17 | "badgeable-column-badge", 18 | match ($shouldBePill()) { 19 | true => 'px-2 !rounded-full', 20 | default => null, 21 | }, 22 | match ($getFontFamily(null)) { 23 | 'sans' => 'font-sans', 24 | 'serif' => 'font-serif', 25 | 'mono' => 'font-mono', 26 | default => null, 27 | }, 28 | match ($getWeight(null) ?? 'medium') { 29 | 'thin' => 'font-thin', 30 | 'extralight' => 'font-extralight', 31 | 'light' => 'font-light', 32 | 'medium' => 'font-medium', 33 | 'semibold' => 'font-semibold', 34 | 'bold' => 'font-bold', 35 | 'extrabold' => 'font-extrabold', 36 | 'black' => 'font-black', 37 | default => null, 38 | } 39 | ]); 40 | @endphp 41 | 42 | {{ $getLabel() }} 43 | @endif 44 | -------------------------------------------------------------------------------- /src/BadgeableColumnServiceProvider.php: -------------------------------------------------------------------------------- 1 | name('filament-badgeable-column') 17 | ->hasAssets() 18 | ->hasViews(); 19 | } 20 | 21 | public function packageBooted(): void 22 | { 23 | FilamentAsset::register([ 24 | Css::make('filament-badgeable-column', __DIR__ . '/../resources/dist/badgeable-column.css') 25 | ], 'awcodes/filament-badgeable-column'); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Components/Badge.php: -------------------------------------------------------------------------------- 1 | name($name); 40 | } 41 | 42 | public static function make(string $name): static 43 | { 44 | $static = app(static::class, ['name' => $name]); 45 | $static->configure(); 46 | 47 | return $static; 48 | } 49 | 50 | public function isPill(bool | Closure | null $condition): static 51 | { 52 | $this->shouldBePill = $condition; 53 | 54 | return $this; 55 | } 56 | 57 | public function size(BadgeSize | string | Closure | null $size): static 58 | { 59 | $this->size = $size; 60 | 61 | return $this; 62 | } 63 | 64 | public function column(Column | Entry $column): static 65 | { 66 | $this->column = $column; 67 | 68 | return $this; 69 | } 70 | 71 | public function getSize(): BadgeSize | string | null 72 | { 73 | return $this->evaluate($this->size); 74 | } 75 | 76 | public function getRecord(): ?Model 77 | { 78 | return $this->column->getRecord(); 79 | } 80 | 81 | protected function resolveDefaultClosureDependencyForEvaluationByName(string $parameterName): array 82 | { 83 | return match ($parameterName) { 84 | 'record' => [$this->getRecord()], 85 | 'state' => [$this->getLabel()], 86 | default => parent::resolveDefaultClosureDependencyForEvaluationByName($parameterName), 87 | }; 88 | } 89 | 90 | public function shouldBePill(): bool 91 | { 92 | return (bool) $this->evaluate($this->shouldBePill); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/Components/BadgeableColumn.php: -------------------------------------------------------------------------------- 1 | html(); 21 | } 22 | 23 | public function asPills(bool | Closure $condition = true): static 24 | { 25 | $this->asPills = $condition; 26 | 27 | return $this; 28 | } 29 | 30 | public function getBadges(array | Closure $badges): string 31 | { 32 | // only evaluate the badges at the point of retrieval, to ensure the rest of the livewire component stack + needed data is available. 33 | $badges = $this->evaluate($badges); 34 | $badgesHtml = ''; 35 | 36 | foreach ($badges as $k => $badge) { 37 | $badgeHtml = $badge 38 | ->column($this) 39 | ->isPill($this->shouldBePills()) 40 | ->render(); 41 | 42 | $badgesHtml .= Str::of($badgeHtml) 43 | ->replace(' ', '') 44 | ->replace('', '') 45 | ->replace('', '') 46 | ->replace('', '') 47 | ->replace('/n', '') 48 | ->trim(); 49 | } 50 | 51 | return $badgesHtml; 52 | } 53 | 54 | public function getPrefix(): string | Htmlable | null 55 | { 56 | $badges = $this->getPrefixBadges(); 57 | 58 | if ($badges) { 59 | return new HtmlString('' . $badges . '' . $this->getSeparator() . ' ' . parent::getPrefix()); 60 | } 61 | 62 | return parent::getPrefix(); 63 | } 64 | 65 | public function getPrefixBadges(): string 66 | { 67 | return $this->getBadges($this->prefixBadges); 68 | } 69 | 70 | public function getSuffix(): string | Htmlable | null 71 | { 72 | $badges = $this->getSuffixBadges(); 73 | 74 | if ($badges) { 75 | return new HtmlString(parent::getSuffix() . ' ' . $this->getSeparator() . '' . $badges . ''); 76 | } 77 | 78 | return parent::getSuffix(); 79 | } 80 | 81 | public function getSuffixBadges(): string 82 | { 83 | return $this->getBadges($this->suffixBadges); 84 | } 85 | 86 | public function prefixBadges(array | Closure $badges): static 87 | { 88 | $this->prefixBadges = $badges; 89 | 90 | return $this; 91 | } 92 | 93 | public function shouldBePills(): bool 94 | { 95 | return (bool) $this->evaluate($this->asPills); 96 | } 97 | 98 | public function suffixBadges(array | Closure $badges): static 99 | { 100 | $this->suffixBadges = $badges; 101 | 102 | return $this; 103 | } 104 | 105 | public function getSeparator(): ?string 106 | { 107 | return $this->evaluate($this->separator) ?? '—'; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/Enums/BadgeSize.php: -------------------------------------------------------------------------------- 1 |