How to Create a Custom Column for Filament Admin Panel
Filament admin panel has a few useful column types we can use in a table:
- TextColumn
- ImageColumn
- SelectColumn
and more.
if you need a type of column that is not available in filament by default, you can create it yourself.
Here we are going to make a column that shows a very simple progress bar.
Install Filament in a Laravel App
inside a laravel app install Filament with composer:
composer require filament/filament:"^2.0"
if you don’t have a user in database create one:
php artisan make:filament-user
Create a Filament Resource
For this example I create a BookResource to have a table that shows a list of books.
php artisan make:filament-resource Book
Create a Database table with Fake Data
we need to create a model and a database table.
php artisan make:model Book
php artisan make:migration create_books_table
migration file:
public function up()
{
Schema::create('books', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->integer('translation_progress')->default(0);
$table->string('author');
$table->string('description');
$table->string('isbn');
$table->string('publish_year');
$table->decimal('price');
$table->timestamps();
});
}
there is a column in the migration called “translation_progress” which we use to show the percentage of the books translation progress in the admin panel.
then we fill the table with fake data to have something to work with.
create a factory:
php artisan make:factory BookFactory
//BookFactory.php
public function definition()
{
return [
'title' => $this->faker->word(),
'translation_progress' => random_int(0, 100),
'author' => $this->faker->name(),
'description' => $this->faker->sentence(),
'isbn' => $this->faker->ean13(),
'publish_year' => $this->faker->year(),
'price' => $this->faker->numberBetween(20, 500),
];
}
create a seeder:
php artisan make:seeder BookSeeder
//BookSeeder.php
use App\Models\Book;
public function run()
{
Book::factory(20)->create();
}
and finally run the seeder to fill the database with 20 rows of fake books data.
php artisan db:seed --class=BookSeeder
Run table-column artisan command
now we have a table of books and it is time to create the custom column.
to create a custom column run this artisan command:
php artisan make:table-column ProgressBar
a Class named “ProgressBar.php ” will be created in “app\Tables\Columns“.
<?php
namespace App\Tables\Columns;
use Filament\Tables\Columns\Column;
class ProgressBar extends Column
{
protected string $view = 'tables.columns.progress-bar';
}
also a blade file named “progress-bar.blade.php file will be created in “resources/views/tables/columns”.
in the blade file we write a simple progress bar code using tailwind.
<div>
<div class="bg-gray-300 h-4 w-20">
<div class="bg-green-500 h-full" style="width: 30%"></div>
</div>
</div>
now in the resource file we have to use the custom column in the table()
method.
use App\Tables\Columns\ProgressBar;
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('title'),
ProgressBar::make('translated'),
Tables\Columns\TextColumn::make('author'),
Tables\Columns\TextColumn::make('publish_year'),
Tables\Columns\TextColumn::make('price'),
])->defaultSort('created_at', 'desc')
->filters([
//
])
->actions([
Tables\Actions\EditAction::make(),
])
->bulkActions([
Tables\Actions\DeleteBulkAction::make(),
]);
}
by default after using the column we have to see the view content in the table but we don’t.

because tailwind classed are not known in these view files. first we have to use the Filament guid for changing appearance to install and include tailwind here.
install tailwind
run this to install tailwind
npm install tailwindcss @tailwindcss/forms @tailwindcss/typography autoprefixer tippy.js --save-dev
create the tailwind.config.js:
npx tailwindcss init
in tailwind.config.js
write this to define colors,forms and typography plugins and most importantly define tailwind for component files in resources folder.
import colors from 'tailwindcss/colors'
import forms from '@tailwindcss/forms'
import typography from '@tailwindcss/typography'
export default {
content: [
'./resources/**/*.blade.php',
'./vendor/filament/**/*.blade.php',
],
darkMode: 'class',
theme: {
extend: {
colors: {
danger: colors.rose,
primary: colors.blue,
success: colors.green,
warning: colors.yellow,
},
},
},
plugins: [
forms,
typography,
],
}
for compiling assets i use laravel mix so first we install it:
npm install laravel-mix@latest --save-dev
after that in webpack.mix.js we register tailwind like this:
const mix = require('laravel-mix');
mix.js('resources/js/app.js', 'public/js')
.postCss('resources/css/filament.css', 'public/css', [
require('tailwindcss'),
]);
make sure you have filament.css file in resources/css
.
put this in this file:
@import '../../vendor/filament/filament/resources/css/app.css';
then register filament.css in a service provider:
public function boot()
{
Filament::serving(function () {
Filament::registerTheme(
mix('css/filament.css'),
);
});
}
finally compile the assets:
npx mix
now take look at the table again it should show the progress bar correctly.

here we set the percentage manually on 30% but we have to make it dynmic.
in the component view we have access to $getRecord
variable which gives us access to the current record in database. Since we defined “translation_progress” column in databse to have the percentage number we can use it here.
so the view will be like this:
<div>
<div class="bg-gray-300 h-4 w-20">
<div class="bg-green-500 h-full" style="width: {{$getRecord()->translation_progress}}%"></div>
</div>
</div>
we replaced the percentage with $getRecord()->translation_progress
to have a dynamic progress bar.
Final Result:

Every record has its own progress percentage.
To summerize creating a custom column in Filament:
- we install filament in a laravel app
- run
make:table-column
artisan command - install, register and compile tailwindcss.
- write your custom view in the column view file.
- use the Column in
table()
method inside a resource class.