Skip to content

Instantly share code, notes, and snippets.

@cpereiraweb
Forked from saade/FilamentServiceProvider.php
Created September 6, 2024 14:54
Show Gist options
  • Save cpereiraweb/e8e5efae6b66e97a10a90b21638836ee to your computer and use it in GitHub Desktop.
Save cpereiraweb/e8e5efae6b66e97a10a90b21638836ee to your computer and use it in GitHub Desktop.
My Filament Defaults
<?php
namespace App\Providers;
use Filament\Actions;
use Filament\Forms;
use Filament\Infolists;
use Filament\Notifications\Notification;
use Filament\Pages;
use Filament\Support\Enums\MaxWidth;
use Filament\Tables;
use Illuminate\Support\ServiceProvider;
use Illuminate\Validation\ValidationException;
class FilamentServiceProvider extends ServiceProvider
{
/**
* Bootstrap services.
*/
public function boot(): void
{
Pages\Page::$reportValidationErrorUsing = function (ValidationException $exception): void {
Notification::make()
->title($exception->getMessage())
->danger()
->send();
};
Pages\Page::$formActionsAreSticky = true;
Actions\ActionGroup::configureUsing(
fn (Actions\ActionGroup $action) => $action->icon('heroicon-o-ellipsis-horizontal')
);
Actions\Action::configureUsing(
fn (Actions\Action $action) => $action
->modalWidth(MaxWidth::Medium)
->closeModalByClickingAway(false)
);
Actions\CreateAction::configureUsing(
fn (Actions\CreateAction $action) => $action
->icon('heroicon-o-plus')
->createAnother(false)
);
Actions\EditAction::configureUsing(
fn (Actions\EditAction $action) => $action->icon('heroicon-o-pencil')
);
Actions\DeleteAction::configureUsing(
fn (Actions\DeleteAction $action) => $action->icon('heroicon-o-trash')
);
Tables\Table::configureUsing(
fn (Tables\Table $table) => $table->filtersFormWidth('md')
);
Tables\Actions\Action::configureUsing(
fn (Tables\Actions\Action $action) => $action
->modalWidth(MaxWidth::Medium)
->closeModalByClickingAway(false)
);
Tables\Actions\CreateAction::configureUsing(
fn (Tables\Actions\CreateAction $action) => $action
->icon('heroicon-o-plus')
->createAnother(false)
);
Tables\Actions\EditAction::configureUsing(
fn (Tables\Actions\EditAction $action) => $action->icon('heroicon-o-pencil')
);
Tables\Actions\DeleteAction::configureUsing(
fn (Tables\Actions\DeleteAction $action) => $action->icon('heroicon-o-trash')
);
Tables\Columns\ImageColumn::configureUsing(
fn (Tables\Columns\ImageColumn $column) => $column->extraImgAttributes(['loading' => 'lazy'])
);
Tables\Columns\TextColumn::configureUsing(
fn (Tables\Columns\TextColumn $column) => $column
->limit(50)
->wrap()
->timezone(config('app.local_timezone'))
);
Tables\Filters\SelectFilter::configureUsing(
fn (Tables\Filters\SelectFilter $filter) => $filter->native(false)
);
Forms\Components\Actions\Action::configureUsing(
fn (Forms\Components\Actions\Action $action) => $action
->modalWidth(MaxWidth::Medium)
->closeModalByClickingAway(false)
);
Forms\Components\Select::configureUsing(
fn (Forms\Components\Select $component) => $component
->native(false)
->selectablePlaceholder(
fn (Forms\Components\Select $component) => ! $component->isRequired(),
)
->searchable(
fn (Forms\Components\Select $component) => $component->hasRelationship()
)
->preload(
fn (Forms\Components\Select $component) => $component->isSearchable()
)
);
Forms\Components\DateTimePicker::configureUsing(
fn (Forms\Components\DateTimePicker $component) => $component
->timezone(config('app.local_timezone'))
->seconds(false)
->maxDate('9999-12-31T23:59')
);
Forms\Components\Repeater::configureUsing(
fn (Forms\Components\Repeater $component) => $component->deleteAction(
fn (Forms\Components\Actions\Action $action) => $action->requiresConfirmation(),
)
);
Forms\Components\Builder::configureUsing(
fn (Forms\Components\Builder $component) => $component->deleteAction(
fn (Forms\Components\Actions\Action $action) => $action->requiresConfirmation(),
)
);
Forms\Components\FileUpload::configureUsing(
fn (Forms\Components\FileUpload $component) => $component->moveFiles()
);
Forms\Components\RichEditor::configureUsing(
fn (Forms\Components\RichEditor $component) => $component->disableToolbarButtons(['blockquote', 'codeBlock'])
);
Infolists\Components\Section::macro('empty', function () {
/** @var Infolists\Components\Section $this */
return $this->extraAttributes(['empty' => true]);
});
}
}
<?php
namespace App\Support;
if (! function_exists('local_now')) {
function local_now(): \Illuminate\Support\Carbon
{
return now(config('app.local_timezone'));
}
}
if (! function_exists('local_date')) {
function local_date(\Illuminate\Support\Carbon|string|null $date = null, string $format = 'd/m/Y', bool $short = false): ?string
{
if (! $date) {
return null;
}
if (! $date instanceof \Illuminate\Support\Carbon) {
$date = \Illuminate\Support\Carbon::parse($date);
}
return $date
->timezone(config('app.local_timezone'))
->when(
fn (\Illuminate\Support\Carbon $carbon) => $short && $carbon->isCurrentYear(),
fn (\Illuminate\Support\Carbon $carbon) => $carbon->translatedFormat(str($format)->replaceMatches('/[\/\-]?\s?[Yy][\/\-]?/', '')),
fn (\Illuminate\Support\Carbon $carbon) => $carbon->translatedFormat($format)
);
}
}
if (! function_exists('local_time')) {
function local_time(\Illuminate\Support\Carbon|string|null $time = null, string $format = 'H:i'): ?string
{
if (! $time) {
return null;
}
if (! $time instanceof \Illuminate\Support\Carbon) {
$time = \Illuminate\Support\Carbon::parse($time);
}
return $time
->timezone(config('app.local_timezone'))
->translatedFormat($format);
}
}
if (! function_exists('local_datetime')) {
function local_datetime(\Illuminate\Support\Carbon|string|null $datetime = null, string $format = 'd/m/Y H:i', bool $short = false): ?string
{
if (! $datetime) {
return null;
}
if (! $datetime instanceof \Illuminate\Support\Carbon) {
$datetime = \Illuminate\Support\Carbon::parse($datetime);
}
return $datetime
->timezone(config('app.local_timezone'))
->when(
fn (\Illuminate\Support\Carbon $carbon) => $short && $carbon->isCurrentYear(),
fn (\Illuminate\Support\Carbon $carbon) => $carbon->translatedFormat(str($format)->replaceMatches('/[\/\-]?\s?[Yy][\/\-]?/', '')),
fn (\Illuminate\Support\Carbon $carbon) => $carbon->translatedFormat($format)
);
}
}
if (! function_exists('array_remove')) {
function array_remove(array &$arr, $key)
{
if (array_key_exists($key, $arr)) {
$val = $arr[$key];
unset($arr[$key]);
return $val;
}
return null;
}
}
if (! function_exists('html')) {
function html(?string $html = null): ?\Illuminate\Support\HtmlString
{
if (! $html) {
return null;
}
return new \Illuminate\Support\HtmlString($html);
}
}
if (! function_exists('md')) {
function md(?string $string = null): ?\Illuminate\Support\HtmlString
{
if (! $string) {
return null;
}
return \Illuminate\Support\Str::of($string)->markdown()->toHtmlString();
}
}
if (! function_exists('blade')) {
function blade(?string $string = null, array $data = [], bool $deleteCachedView = false): ?string
{
if (! $string) {
return null;
}
return \Illuminate\Support\Facades\Blade::render($string, $data, $deleteCachedView);
}
}
if (! function_exists('enum_equals')) {
function enum_equals(\BackedEnum|array $enum, \BackedEnum|string|int|null $value): bool
{
if (is_array($enum)) {
return array_reduce($enum, fn (bool $carry, \BackedEnum $enum) => $carry || enum_equals($enum, $value), false);
}
if (! $value instanceof \BackedEnum) {
return $enum::tryFrom($value) === $enum;
}
return $enum === $value;
}
}
if (! function_exists('tenant')) {
/**
* @template TValue
*
* @param class-string<TValue> $class
* @param string|null $attribute
*
* @return TValue|mixed
*/
function tenant(string $class, ?string $attribute = null): mixed
{
return once(function () use ($class, $attribute) {
$tenant = \Filament\Facades\Filament::getTenant();
if (! $tenant instanceof $class) {
return null;
}
if (is_null($attribute)) {
return $tenant;
}
return $tenant?->getAttribute($attribute) ?? null;
});
}
}
if (! function_exists('css_classes')) {
function css_classes($classes = []): string
{
return \Illuminate\Support\Arr::toCssClasses($classes);
}
}
if (! function_exists('mask')) {
/**
* Applies mask in the value.
*
* @param string $mask
* @param $value
*
* @return string
*/
function mask(string $mask, $value): ?string
{
if (is_null($value)) {
return null;
}
// Apply mask
$value = str_replace(' ', '', $value);
$replacedStr = \Illuminate\Support\Str::replaceArray('#', str_split($value), $mask);
// Get filled substring
$posSymbol = strpos($replacedStr, '#', strlen($value));
$replacedStrLen = strlen($replacedStr);
$length = $posSymbol ? $replacedStrLen - ($replacedStrLen - $posSymbol) : $replacedStrLen;
return substr($replacedStr, 0, $length);
}
}
@import '/vendor/filament/filament/resources/css/theme.css';
@config 'tailwind.config.js';
html:not(:has(.fi-topbar-with-navigation)) {
.fi-sidebar,
.fi-sidebar-header,
aside {
@apply !ring-0 !shadow-none;
}
.fi-topbar {
@apply relative;
nav {
@apply !shadow-none !ring-0;
&::-webkit-scrollbar {
@apply w-0;
}
}
}
&:not(.dark) {
.fi-sidebar {
@apply !bg-white !ring-1 !ring-gray-950/5;
}
.fi-sidebar-nav {
@apply !bg-white;
}
.fi-topbar nav {
@apply !bg-transparent;
}
.fi-modal-window {
@apply !bg-gray-50;
}
}
&.dark {
.fi-sidebar {
@apply !bg-gray-900 !ring-white/10;
}
.fi-topbar nav {
@apply !bg-gray-950;
}
.fi-modal-window {
@apply !bg-gray-950;
}
}
}
html {
&:not(.dark) {
body {
@apply !bg-gray-50;
}
.filepond--image-preview,
.filepond--item-panel {
@apply bg-gray-100;
}
}
&.dark {
.filepond--image-preview,
.filepond--item-panel {
@apply bg-gray-800;
}
}
}
[x-sortable-handle] button {
@apply cursor-grab active:cursor-grabbing;
}
.fi-section {
.fi-section-content-ctn {
@apply !border-none;
}
}
/* Quando usar um component Tabs dentro de um Builder, o Builder fica compacto */
.fi-fo-builder {
&[tabs] {
.fi-fo-builder-item {
.fi-fo-builder-item-content {
@apply !p-0;
.fi-fo-tabs {
@apply !ring-0 !rounded-t-none;
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment