Merge branch '3.x' into upg3

This commit is contained in:
Dan Harrin
2023-06-14 22:01:22 +01:00
79 changed files with 970 additions and 1209 deletions
@@ -8,7 +8,7 @@ use Filament\Http\Middleware\DispatchServingFilamentEvent;
use Filament\Pages;
use Filament\Panel;
use Filament\PanelProvider;
use Filament\Support\Color;
use Filament\Support\Colors\Color;
use Filament\Widgets;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use Illuminate\Cookie\Middleware\EncryptCookies;
@@ -29,7 +29,9 @@ class AdminPanelProvider extends PanelProvider
->id('admin')
->path('admin')
->login()
->primaryColor(Color::Amber)
->colors([
'primary' => Color::Amber,
])
->discoverResources(in: app_path('Filament/Resources'), for: 'App\\Filament\\Resources')
->discoverPages(in: app_path('Filament/Pages'), for: 'App\\Filament\\Pages')
->pages([
+67 -57
View File
@@ -2562,9 +2562,9 @@
}
},
"node_modules/@types/eslint": {
"version": "8.40.1",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.40.1.tgz",
"integrity": "sha512-vRb792M4mF1FBT+eoLecmkpLXwxsBHvWWRGJjzbYANBM6DtiJc6yETyv4rqDA6QNjF1pkj1U7LMA6dGb3VYlHw==",
"version": "8.40.2",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.40.2.tgz",
"integrity": "sha512-PRVjQ4Eh9z9pmmtaq8nTjZjQwKFk7YIHIud3lRoKRBgUQjgjRmoGxxGEPXQkF+lH7QkHJRNr5F4aBgYCW0lqpQ==",
"dev": true,
"dependencies": {
"@types/estree": "*",
@@ -2712,9 +2712,9 @@
"dev": true
},
"node_modules/@types/node": {
"version": "20.3.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.0.tgz",
"integrity": "sha512-cumHmIAf6On83X7yP+LrsEyUOf/YlociZelmpRYaGFydoaPdxdt80MAbu6vWerQT2COCp2nPvHdsbD7tHn/YlQ==",
"version": "20.3.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.1.tgz",
"integrity": "sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg==",
"dev": true
},
"node_modules/@types/parse-json": {
@@ -3634,9 +3634,9 @@
}
},
"node_modules/browserslist": {
"version": "4.21.7",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.7.tgz",
"integrity": "sha512-BauCXrQ7I2ftSqd2mvKHGo85XR0u7Ru3C/Hxsy/0TkfCtjrmAbPdzLGasmoiBxplpDXlPvdjX9u7srIMfgasNA==",
"version": "4.21.8",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.8.tgz",
"integrity": "sha512-j+7xYe+v+q2Id9qbBeCI8WX5NmZSRe8es1+0xntD/+gaWXznP8tFEkv5IgSaHf5dS1YwVMbX/4W6m937mj+wQw==",
"dev": true,
"funding": [
{
@@ -3653,8 +3653,8 @@
}
],
"dependencies": {
"caniuse-lite": "^1.0.30001489",
"electron-to-chromium": "^1.4.411",
"caniuse-lite": "^1.0.30001502",
"electron-to-chromium": "^1.4.428",
"node-releases": "^2.0.12",
"update-browserslist-db": "^1.0.11"
},
@@ -3757,9 +3757,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001502",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001502.tgz",
"integrity": "sha512-AZ+9tFXw1sS0o0jcpJQIXvFTOB/xGiQ4OQ2t98QX3NDn2EZTSRBC801gxrsGgViuq2ak/NLkNgSNEPtCr5lfKg==",
"version": "1.0.30001503",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001503.tgz",
"integrity": "sha512-Sf9NiF+wZxPfzv8Z3iS0rXM1Do+iOy2Lxvib38glFX+08TCYYYGR5fRJXk4d77C4AYwhUjgYgMsMudbh2TqCKw==",
"dev": true,
"funding": [
{
@@ -4307,9 +4307,9 @@
}
},
"node_modules/css-loader/node_modules/schema-utils": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.2.0.tgz",
"integrity": "sha512-0zTyLGyDJYd/MBxG1AhJkKa6fpEBds4OQO2ut0w7OYG+ZGhGea09lijvzsqegYSik88zc7cUtIlnnO+/BvD6gQ==",
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
"integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
"dev": true,
"dependencies": {
"@types/json-schema": "^7.0.8",
@@ -4783,9 +4783,9 @@
"dev": true
},
"node_modules/electron-to-chromium": {
"version": "1.4.427",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.427.tgz",
"integrity": "sha512-HK3r9l+Jm8dYAm1ctXEWIC+hV60zfcjS9UA5BDlYvnI5S7PU/yytjpvSrTNrSSRRkuu3tDyZhdkwIczh+0DWaw==",
"version": "1.4.430",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.430.tgz",
"integrity": "sha512-FytjTbGwz///F+ToZ5XSeXbbSaXalsVRXsz2mHityI5gfxft7ieW3HqFLkU5V1aIrY42aflICqbmFoDxW10etg==",
"dev": true
},
"node_modules/elliptic": {
@@ -4834,9 +4834,9 @@
}
},
"node_modules/enhanced-resolve": {
"version": "5.14.1",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.14.1.tgz",
"integrity": "sha512-Vklwq2vDKtl0y/vtwjSesgJ5MYS7Etuk5txS8VdKL4AOS1aUlD96zqIfsOSLQsdv3xgMRbtkWM8eG9XDfKUPow==",
"version": "5.15.0",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz",
"integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==",
"dev": true,
"dependencies": {
"graceful-fs": "^4.2.4",
@@ -5360,9 +5360,9 @@
}
},
"node_modules/file-loader/node_modules/schema-utils": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.2.0.tgz",
"integrity": "sha512-0zTyLGyDJYd/MBxG1AhJkKa6fpEBds4OQO2ut0w7OYG+ZGhGea09lijvzsqegYSik88zc7cUtIlnnO+/BvD6gQ==",
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
"integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
"dev": true,
"dependencies": {
"@types/json-schema": "^7.0.8",
@@ -6026,10 +6026,20 @@
}
},
"node_modules/html-entities": {
"version": "2.3.5",
"resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.5.tgz",
"integrity": "sha512-72TJlcMkYsEJASa/3HnX7VT59htM7iSHbH59NSZbtc+22Ap0Txnlx91sfeB+/A7wNZg7UxtZdhAW4y+/jimrdg==",
"dev": true
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.6.tgz",
"integrity": "sha512-9o0+dcpIw2/HxkNuYKxSJUF/MMRZQECK4GnF+oQOmJ83yCVHTWgCH5aOXxK5bozNRmM8wtgryjHD3uloPBDEGw==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/mdevils"
},
{
"type": "patreon",
"url": "https://patreon.com/mdevils"
}
]
},
"node_modules/html-loader": {
"version": "1.3.2",
@@ -6054,9 +6064,9 @@
}
},
"node_modules/html-loader/node_modules/schema-utils": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.2.0.tgz",
"integrity": "sha512-0zTyLGyDJYd/MBxG1AhJkKa6fpEBds4OQO2ut0w7OYG+ZGhGea09lijvzsqegYSik88zc7cUtIlnnO+/BvD6gQ==",
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
"integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
"dev": true,
"dependencies": {
"@types/json-schema": "^7.0.8",
@@ -7354,9 +7364,9 @@
}
},
"node_modules/mini-css-extract-plugin/node_modules/schema-utils": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.2.0.tgz",
"integrity": "sha512-0zTyLGyDJYd/MBxG1AhJkKa6fpEBds4OQO2ut0w7OYG+ZGhGea09lijvzsqegYSik88zc7cUtIlnnO+/BvD6gQ==",
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
"integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
"dev": true,
"dependencies": {
"@types/json-schema": "^7.0.8",
@@ -8950,9 +8960,9 @@
}
},
"node_modules/pusher-js/node_modules/@types/node": {
"version": "14.18.50",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.50.tgz",
"integrity": "sha512-DdJP83r2Zp5x32la3jEzjIlB85+2gMPUHP1xFL2xFORzbJ94sNwh4b6ZBaF6EN/7BTII6mba3yakqfLEnt5eZg==",
"version": "14.18.51",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.51.tgz",
"integrity": "sha512-P9bsdGFPpVtofEKlhWMVS2qqx1A/rt9QBfihWlklfHHpUpjtYse5AzFz6j4DWrARLYh6gRnw9+5+DJcrq3KvBA==",
"dev": true
},
"node_modules/qs": {
@@ -10068,9 +10078,9 @@
}
},
"node_modules/style-loader/node_modules/schema-utils": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.2.0.tgz",
"integrity": "sha512-0zTyLGyDJYd/MBxG1AhJkKa6fpEBds4OQO2ut0w7OYG+ZGhGea09lijvzsqegYSik88zc7cUtIlnnO+/BvD6gQ==",
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
"integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
"dev": true,
"dependencies": {
"@types/json-schema": "^7.0.8",
@@ -10314,9 +10324,9 @@
}
},
"node_modules/terser": {
"version": "5.17.7",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.17.7.tgz",
"integrity": "sha512-/bi0Zm2C6VAexlGgLlVxA0P2lru/sdLyfCVaRMfKVo9nWxbmz7f/sD8VPybPeSUJaJcwmCJis9pBIhcVcG1QcQ==",
"version": "5.18.0",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.18.0.tgz",
"integrity": "sha512-pdL757Ig5a0I+owA42l6tIuEycRuM7FPY4n62h44mRLRfnOxJkkOHd6i89dOpwZlpF6JXBwaAHF6yWzFrt+QyA==",
"dev": true,
"dependencies": {
"@jridgewell/source-map": "^0.3.3",
@@ -10366,9 +10376,9 @@
}
},
"node_modules/terser-webpack-plugin/node_modules/schema-utils": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.2.0.tgz",
"integrity": "sha512-0zTyLGyDJYd/MBxG1AhJkKa6fpEBds4OQO2ut0w7OYG+ZGhGea09lijvzsqegYSik88zc7cUtIlnnO+/BvD6gQ==",
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
"integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
"dev": true,
"dependencies": {
"@types/json-schema": "^7.0.8",
@@ -11013,9 +11023,9 @@
"dev": true
},
"node_modules/webpack-dev-middleware/node_modules/schema-utils": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.1.0.tgz",
"integrity": "sha512-Jw+GZVbP5IggB2WAn6UHI02LBwGmsIeYN/lNbSMZyDziQ7jmtAUrqKqDja+W89YHVs+KL/3IkIMltAklqB1vAw==",
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz",
"integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==",
"dev": true,
"dependencies": {
"@types/json-schema": "^7.0.9",
@@ -11125,9 +11135,9 @@
"dev": true
},
"node_modules/webpack-dev-server/node_modules/schema-utils": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.1.0.tgz",
"integrity": "sha512-Jw+GZVbP5IggB2WAn6UHI02LBwGmsIeYN/lNbSMZyDziQ7jmtAUrqKqDja+W89YHVs+KL/3IkIMltAklqB1vAw==",
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz",
"integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==",
"dev": true,
"dependencies": {
"@types/json-schema": "^7.0.9",
@@ -11185,9 +11195,9 @@
}
},
"node_modules/webpack/node_modules/schema-utils": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.2.0.tgz",
"integrity": "sha512-0zTyLGyDJYd/MBxG1AhJkKa6fpEBds4OQO2ut0w7OYG+ZGhGea09lijvzsqegYSik88zc7cUtIlnnO+/BvD6gQ==",
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
"integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
"dev": true,
"dependencies": {
"@types/json-schema": "^7.0.8",
+1 -1
View File
@@ -3,7 +3,7 @@
"type": "module",
"scripts": {
"dev:js": "node bin/build.js --dev",
"dev:css": "npx tailwindcss -c ./packages/panels/tailwind.config.js -i ./packages/panels/resources/css/theme.css -o ./packages/panels/dist/theme.css --minify",
"dev:css": "npx tailwindcss -c ./packages/panels/tailwind.config.js -i ./packages/panels/resources/css/theme.css -o ./packages/panels/dist/theme.css --watch",
"dev": "npm-run-all --parallel dev:*",
"build:js": "node bin/build.js",
"build:css": "npx tailwindcss -c ./packages/panels/tailwind.config.js -i ./packages/panels/resources/css/theme.css -o ./packages/panels/dist/theme.css --minify",
+6 -4
View File
@@ -4,7 +4,9 @@ namespace Filament\Actions;
use Filament\Actions\Contracts\HasLivewire;
use Filament\Support\Components\ViewComponent;
use Filament\Support\Concerns\HasColor;
use Filament\Support\Concerns\HasExtraAttributes;
use Filament\Support\Concerns\HasIcon;
use Livewire\Component;
class ActionGroup extends ViewComponent implements HasLivewire
@@ -15,17 +17,17 @@ class ActionGroup extends ViewComponent implements HasLivewire
use Concerns\CanBeInline;
use Concerns\CanBeLabeledFrom;
use Concerns\CanBeOutlined;
use Concerns\HasColor;
use Concerns\HasDropdown;
use Concerns\HasGroupedIcon;
use Concerns\HasIcon {
getIcon as getBaseIcon;
}
use Concerns\HasIndicator;
use Concerns\HasLabel;
use Concerns\HasSize;
use Concerns\HasTooltip;
use HasColor;
use HasExtraAttributes;
use HasIcon {
getIcon as getBaseIcon;
}
/**
* @var array<StaticAction | ActionGroup>
@@ -1,22 +0,0 @@
<?php
namespace Filament\Actions\Concerns;
use Closure;
trait HasColor
{
protected string | Closure | null $color = null;
public function color(string | Closure | null $color): static
{
$this->color = $color;
return $this;
}
public function getColor(): ?string
{
return $this->evaluate($this->color);
}
}
-50
View File
@@ -1,50 +0,0 @@
<?php
namespace Filament\Actions\Concerns;
use Closure;
trait HasIcon
{
protected string | Closure | null $icon = null;
protected string | Closure | null $iconPosition = null;
protected string | Closure | null $iconSize = null;
public function icon(string | Closure | null $icon): static
{
$this->icon = $icon;
return $this;
}
public function iconPosition(string | Closure | null $position): static
{
$this->iconPosition = $position;
return $this;
}
public function iconSize(string | Closure | null $size): static
{
$this->iconSize = $size;
return $this;
}
public function getIcon(): ?string
{
return $this->evaluate($this->icon);
}
public function getIconPosition(): ?string
{
return $this->evaluate($this->iconPosition);
}
public function getIconSize(): ?string
{
return $this->evaluate($this->iconSize);
}
}
+12 -3
View File
@@ -8,7 +8,10 @@ trait HasIndicator
{
protected string | Closure | null $indicator = null;
protected string | Closure | null $indicatorColor = null;
/**
* @var string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | Closure | null
*/
protected string | array | Closure | null $indicatorColor = null;
public function indicator(string | Closure | null $indicator): static
{
@@ -17,7 +20,10 @@ trait HasIndicator
return $this;
}
public function indicatorColor(string | Closure | null $color): static
/**
* @param string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | Closure | null $color
*/
public function indicatorColor(string | array | Closure | null $color): static
{
$this->indicatorColor = $color;
@@ -29,7 +35,10 @@ trait HasIndicator
return $this->evaluate($this->indicator);
}
public function getIndicatorColor(): ?string
/**
* @return string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null
*/
public function getIndicatorColor(): string | array | null
{
return $this->evaluate($this->indicatorColor);
}
+4 -2
View File
@@ -3,7 +3,9 @@
namespace Filament\Actions;
use Filament\Support\Components\ViewComponent;
use Filament\Support\Concerns\HasColor;
use Filament\Support\Concerns\HasExtraAttributes;
use Filament\Support\Concerns\HasIcon;
use Illuminate\Support\Collection;
use Illuminate\Support\Js;
use Illuminate\Support\Traits\Conditionable;
@@ -22,9 +24,7 @@ class StaticAction extends ViewComponent
use Concerns\CanSubmitForm;
use Concerns\HasAction;
use Concerns\HasArguments;
use Concerns\HasColor;
use Concerns\HasGroupedIcon;
use Concerns\HasIcon;
use Concerns\HasIndicator;
use Concerns\HasKeyBindings;
use Concerns\HasLabel;
@@ -32,6 +32,8 @@ class StaticAction extends ViewComponent
use Concerns\HasSize;
use Concerns\HasTooltip;
use Conditionable;
use HasColor;
use HasIcon;
use HasExtraAttributes;
public const BUTTON_VIEW = 'filament-actions::button-action';
@@ -363,7 +363,7 @@ class TestsActions
public function assertActionHasColor(): Closure
{
return function (string | array $name, string $color, $record = null): static {
return function (string | array $name, string | array $color, $record = null): static {
/** @var array<string> $name */
/** @phpstan-ignore-next-line */
$name = $this->parseNestedActionName($name);
@@ -387,7 +387,7 @@ class TestsActions
public function assertActionDoesNotHaveColor(): Closure
{
return function (string | array $name, string $color, $record = null): static {
return function (string | array $name, string | array $color, $record = null): static {
/** @var array<string> $name */
/** @phpstan-ignore-next-line */
$name = $this->parseNestedActionName($name);
@@ -1,24 +1,18 @@
@props([
'actions' => [],
'color' => null,
'color' => 'gray',
'icon' => null,
])
<div
{{
$attributes->class([
'filament-forms-field-wrapper-hint flex items-center space-x-2 rtl:space-x-reverse',
match ($color) {
'danger' => 'text-danger-500 dark:text-danger-300',
'gray', null => 'text-gray-500 dark:text-gray-300',
'info' => 'text-info-500 dark:text-info-300',
'primary' => 'text-primary-500 dark:text-primary-300',
'secondary' => 'text-secondary-500 dark:text-secondary-300',
'success' => 'text-success-500 dark:text-success-300',
'warning' => 'text-warning-500 dark:text-warning-300',
default => $color,
},
])
$attributes
->class([
'filament-forms-field-wrapper-hint flex items-center space-x-2 text-custom-500 rtl:space-x-reverse dark:text-custom-300',
])
->style([
\Filament\Support\get_color_css_variables($color, shades: [300, 500]),
])
}}
>
@if ($slot->isNotEmpty())
@@ -1,7 +1,7 @@
<x-dynamic-component :component="$getFieldWrapperView()" :field="$field">
@php
$offColor = $getOffColor();
$onColor = $getOnColor();
$offColor = $getOffColor() ?? 'gray';
$onColor = $getOnColor() ?? 'primary';
$statePath = $getStatePath();
@endphp
@@ -14,30 +14,22 @@
state
? '{{
match ($onColor) {
'danger' => 'bg-danger-600',
'gray' => 'bg-gray-600',
'info' => 'bg-info-600',
'primary', null => 'bg-primary-600',
'secondary' => 'bg-secondary-600',
'success' => 'bg-success-600',
'warning' => 'bg-warning-600',
default => $onColor,
'gray' => 'bg-gray-200 dark:bg-gray-700',
default => 'bg-custom-600',
}
}}'
: '{{
match ($offColor) {
'danger' => 'bg-danger-600',
'gray' => 'bg-gray-600',
'info' => 'bg-info-600',
'primary' => 'bg-primary-600',
'secondary' => 'bg-secondary-600',
'success' => 'bg-success-600',
'warning' => 'bg-warning-600',
null => 'bg-gray-200 dark:bg-gray-700',
default => $offColor,
'gray' => 'bg-gray-200 dark:bg-gray-700',
default => 'bg-custom-600',
}
}}'
"
x-bind:style="
state
? '{{ \Filament\Support\get_color_css_variables($onColor, shades: [600]) }}'
: '{{ \Filament\Support\get_color_css_variables($offColor, shades: [600]) }}'
"
{{
$attributes
->merge([
@@ -75,15 +67,8 @@
:name="$getOffIcon()"
alias="forms::components.toggle.off"
:color="match ($offColor) {
'danger' => 'text-danger-600',
'gray' => 'text-gray-600',
'info' => 'text-info-600',
'primary' => 'text-primary-600',
'secondary' => 'text-secondary-600',
'success' => 'text-success-600',
'warning' => 'text-warning-600',
null => 'text-gray-400 dark:text-gray-700',
default => $offColor,
'gray' => 'text-gray-400 dark:text-gray-700',
default => 'text-custom-600',
}"
size="h-3 w-3"
/>
@@ -103,14 +88,8 @@
:name="$getOnIcon()"
alias="forms::components.toggle.on"
:color="match ($onColor) {
'danger' => 'text-danger-600',
'gray' => 'text-gray-600',
'info' => 'text-info-600',
'primary', null => 'text-primary-600',
'secondary' => 'text-secondary-600',
'success' => 'text-success-600',
'warning' => 'text-warning-600',
default => $onColor,
'gray' => 'text-gray-400 dark:text-gray-700',
default => 'text-custom-600',
}"
size="h-3 w-3"
x-cloak="x-cloak"
+2 -2
View File
@@ -23,9 +23,9 @@ class Card extends Component implements CanEntangleWithSingularRelationships
}
/**
* @param array<Component> $schema
* @param array<Component> | Closure $schema
*/
public static function make(array $schema = []): static
public static function make(array | Closure $schema = []): static
{
$static = app(static::class, ['schema' => $schema]);
$static->configure();
@@ -21,7 +21,10 @@ trait HasHint
*/
protected array $hintActions = [];
protected string | Closure | null $hintColor = null;
/**
* @var string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | Closure | null
*/
protected string | array | Closure | null $hintColor = null;
protected string | Closure | null $hintIcon = null;
@@ -32,9 +35,12 @@ trait HasHint
return $this;
}
public function hintColor(string | Closure | null $hintColor): static
/**
* @param string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | Closure | null $color
*/
public function hintColor(string | array | Closure | null $color): static
{
$this->hintColor = $hintColor;
$this->hintColor = $color;
return $this;
}
@@ -71,7 +77,10 @@ trait HasHint
return $this->evaluate($this->hint);
}
public function getHintColor(): ?string
/**
* @return string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null
*/
public function getHintColor(): string | array | null
{
return $this->evaluate($this->hintColor);
}
@@ -6,30 +6,48 @@ use Closure;
trait HasToggleColors
{
protected string | Closure | null $offColor = null;
/**
* @var string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | Closure | null
*/
protected string | array | Closure | null $offColor = null;
protected string | Closure | null $onColor = null;
/**
* @var string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | Closure | null
*/
protected string | array | Closure | null $onColor = null;
public function offColor(string | Closure | null $color): static
/**
* @param string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | Closure | null $color
*/
public function offColor(string | array | Closure | null $color): static
{
$this->offColor = $color;
return $this;
}
public function onColor(string | Closure | null $color): static
/**
* @param string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | Closure | null $color
*/
public function onColor(string | array | Closure | null $color): static
{
$this->onColor = $color;
return $this;
}
public function getOffColor(): ?string
/**
* @return string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null
*/
public function getOffColor(): string | array | null
{
return $this->evaluate($this->offColor);
}
public function getOnColor(): ?string
/**
* @return string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null
*/
public function getOnColor(): string | array | null
{
return $this->evaluate($this->onColor);
}
+2 -2
View File
@@ -23,9 +23,9 @@ class Group extends Component implements CanEntangleWithSingularRelationships
}
/**
* @param array<Component> $schema
* @param array<Component> | Closure $schema
*/
public static function make(array $schema = []): static
public static function make(array | Closure $schema = []): static
{
$static = app(static::class, ['schema' => $schema]);
$static->configure();
+12 -3
View File
@@ -18,7 +18,10 @@ class Tab extends Component implements CanConcealComponents
protected string | Closure | null $icon = null;
protected string | Closure | null $iconColor = null;
/**
* @var string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | Closure | null
*/
protected string | array | Closure | null $iconColor = null;
protected string | Closure | null $iconPosition = null;
@@ -43,7 +46,10 @@ class Tab extends Component implements CanConcealComponents
return $this;
}
public function iconColor(string | Closure | null $color): static
/**
* @param string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | Closure | null $color
*/
public function iconColor(string | array | Closure | null $color): static
{
$this->iconColor = $color;
@@ -87,7 +93,10 @@ class Tab extends Component implements CanConcealComponents
return $this->evaluate($this->iconPosition) ?? 'before';
}
public function getIconColor(): ?string
/**
* @return string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null
*/
public function getIconColor(): string | array | null
{
return $this->evaluate($this->iconColor);
}
@@ -1,24 +1,18 @@
@props([
'actions' => [],
'color' => null,
'color' => 'gray',
'icon' => null,
])
<div
{{
$attributes->class([
'filament-infolists-entry-wrapper-hint flex items-center space-x-2 rtl:space-x-reverse',
match ($color) {
'danger' => 'text-danger-500 dark:text-danger-300',
'gray', null => 'text-gray-500 dark:text-gray-300',
'info' => 'text-info-500 dark:text-info-300',
'primary' => 'text-primary-500 dark:text-primary-300',
'secondary' => 'text-secondary-500 dark:text-secondary-300',
'success' => 'text-success-500 dark:text-success-300',
'warning' => 'text-warning-500 dark:text-warning-300',
default => $color,
},
])
$attributes
->class([
'filament-infolists-entry-wrapper-hint flex items-center space-x-2 text-custom-500 rtl:space-x-reverse dark:text-custom-300',
])
->styles([
\Filament\Support\get_color_css_variables($color, shades: [300, 500]),
])
}}
>
@if ($slot->isNotEmpty())
@@ -13,16 +13,7 @@
<x-filament::icon
:name="$icon"
alias="infolists::entries.icon"
:color="match ($color = $getColor($state)) {
'danger' => 'text-danger-500',
'gray', null => 'text-gray-500',
'info' => 'text-info-500',
'primary' => 'text-primary-500',
'secondary' => 'text-secondary-500',
'success' => 'text-success-500',
'warning' => 'text-warning-500',
default => $color,
}"
color="text-custom-500"
:size="match ($size = ($getSize($state) ?? 'lg')) {
'xs' => 'h-3 w-3 filament-infolists-icon-entry-icon-size-xs',
'sm' => 'h-4 w-4 filament-infolists-icon-entry-icon-size-sm',
@@ -31,6 +22,7 @@
'xl' => 'h-7 w-7 filament-infolists-icon-entry-icon-size-xl',
default => $size,
}"
:style="\Filament\Support\get_color_css_variables($getColor($state), shades: [500])"
/>
@endif
@endforeach
@@ -60,6 +60,7 @@
@foreach ($arrayState as $state)
@php
$formattedState = $formatState($state);
$color = $getColor($state) ?? 'gray';
$icon = $getIcon($state);
@endphp
@@ -71,26 +72,14 @@
'min-h-6 justify-center whitespace-nowrap rounded-xl px-2 py-0.5' => $isBadge,
'prose max-w-none dark:prose-invert' => $isProse,
'whitespace-normal' => $canWrap,
($isBadge ? match ($color = $getColor($state)) {
'danger' => 'bg-danger-500/10 text-danger-700 dark:text-danger-500',
'gray', null => 'bg-gray-500/10 text-gray-700 dark:bg-gray-500/20 dark:text-gray-300',
'info' => 'bg-info-500/10 text-info-700 dark:text-info-500',
'primary' => 'bg-primary-500/10 text-primary-700 dark:text-primary-500',
'secondary' => 'bg-secondary-500/10 text-secondary-700 dark:text-secondary-500',
'success' => 'bg-success-500/10 text-success-700 dark:text-success-500',
'warning' => 'bg-warning-500/10 text-warning-700 dark:text-warning-500',
default => $color,
} : null),
((! ($isBadge || $url)) ? match ($color = $getColor($state)) {
'danger' => 'text-danger-600',
'gray' => 'text-gray-600 dark:text-gray-400',
'info' => 'text-info-600',
'primary' => 'text-primary-600',
'secondary' => 'text-secondary-600',
'success' => 'text-success-600',
'warning' => 'text-warning-600',
default => $color,
} : null),
match ($color) {
'gray' => 'bg-gray-500/10 text-gray-700 dark:bg-gray-500/20 dark:text-gray-300',
default => 'bg-custom-500/10 text-custom-700 dark:text-custom-500',
} => $isBadge,
match ($color) {
'gray' => null,
default => 'text-custom-600',
} => ! ($isBadge || $url),
($isProse ? match ($size = $getSize($state)) {
'sm' => 'prose-sm',
'base', 'md', null => 'prose-base',
@@ -121,6 +110,15 @@
default => null,
},
])
@style([
\Filament\Support\get_color_css_variables(
$color,
shades: match (true) {
$isBadge => [500, 700],
! ($isBadge || $url) => [600],
},
) => $color !== 'gray',
])
>
@if ($icon && $iconPosition === 'before')
<x-filament::icon
+2 -2
View File
@@ -22,9 +22,9 @@ class Card extends Component
}
/**
* @param array<Component> $schema
* @param array<Component> | Closure $schema
*/
public static function make(array $schema = []): static
public static function make(array | Closure $schema = []): static
{
$static = app(static::class, ['schema' => $schema]);
$static->configure();
@@ -8,9 +8,15 @@ use Filament\Support\Contracts\HasColor as ColorInterface;
trait HasColor
{
protected string | bool | Closure | null $color = null;
/**
* @var string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | bool | Closure | null
*/
protected string | array | bool | Closure | null $color = null;
public function color(string | bool | Closure | null $color): static
/**
* @param string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | bool | Closure | null $color
*/
public function color(string | array | bool | Closure | null $color): static
{
$this->color = $color;
@@ -43,7 +49,10 @@ trait HasColor
return $this;
}
public function getColor(mixed $state): ?string
/**
* @return string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null
*/
public function getColor(mixed $state): string | array | null
{
$color = $this->evaluate($this->color, [
'state' => $state,
@@ -21,7 +21,10 @@ trait HasHint
*/
protected array $hintActions = [];
protected string | Closure | null $hintColor = null;
/**
* @var string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | Closure | null
*/
protected string | array | Closure | null $hintColor = null;
protected string | Closure | null $hintIcon = null;
@@ -32,9 +35,12 @@ trait HasHint
return $this;
}
public function hintColor(string | Closure | null $hintColor): static
/**
* @param string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | Closure | null $color
*/
public function hintColor(string | array | Closure | null $color): static
{
$this->hintColor = $hintColor;
$this->hintColor = $color;
return $this;
}
@@ -71,7 +77,10 @@ trait HasHint
return $this->evaluate($this->hint);
}
public function getHintColor(): ?string
/**
* @return string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null
*/
public function getHintColor(): string | array | null
{
return $this->evaluate($this->hintColor);
}
+2 -2
View File
@@ -22,9 +22,9 @@ class Group extends Component
}
/**
* @param array<Component> $schema
* @param array<Component> | Closure $schema
*/
public static function make(array $schema = []): static
public static function make(array | Closure $schema = []): static
{
$static = app(static::class, ['schema' => $schema]);
$static->configure();
@@ -21,11 +21,17 @@ class IconEntry extends Entry
protected bool | Closure $isBoolean = false;
protected string | Closure | null $falseColor = null;
/**
* @var string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | Closure | null
*/
protected string | array | Closure | null $falseColor = null;
protected string | Closure | null $falseIcon = null;
protected string | Closure | null $trueColor = null;
/**
* @var string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | Closure | null
*/
protected string | array | Closure | null $trueColor = null;
protected string | Closure | null $trueIcon = null;
@@ -36,7 +42,10 @@ class IconEntry extends Entry
return $this;
}
public function false(string | Closure | null $icon = null, string | Closure | null $color = null): static
/**
* @param string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | Closure | null $color
*/
public function false(string | Closure | null $icon = null, string | array | Closure | null $color = null): static
{
$this->falseIcon($icon);
$this->falseColor($color);
@@ -44,7 +53,10 @@ class IconEntry extends Entry
return $this;
}
public function falseColor(string | Closure | null $color): static
/**
* @param string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | Closure | null $color
*/
public function falseColor(string | array | Closure | null $color): static
{
$this->boolean();
$this->falseColor = $color;
@@ -60,7 +72,10 @@ class IconEntry extends Entry
return $this;
}
public function true(string | Closure | null $icon = null, string | Closure | null $color = null): static
/**
* @param string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | Closure | null $color
*/
public function true(string | Closure | null $icon = null, string | array | Closure | null $color = null): static
{
$this->trueIcon($icon);
$this->trueColor($color);
@@ -68,7 +83,10 @@ class IconEntry extends Entry
return $this;
}
public function trueColor(string | Closure | null $color): static
/**
* @param string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | Closure | null $color
*/
public function trueColor(string | array | Closure | null $color): static
{
$this->boolean();
$this->trueColor = $color;
@@ -101,7 +119,10 @@ class IconEntry extends Entry
return $state ? $this->getTrueIcon() : $this->getFalseIcon();
}
public function getColor(mixed $state): ?string
/**
* @return string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null
*/
public function getColor(mixed $state): string | array | null
{
if (filled($color = $this->getBaseColor($state))) {
return $color;
@@ -118,7 +139,10 @@ class IconEntry extends Entry
return $state ? $this->getTrueColor() : $this->getFalseColor();
}
public function getFalseColor(): string
/**
* @return string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string}
*/
public function getFalseColor(): string | array
{
return $this->evaluate($this->falseColor) ?? 'danger';
}
@@ -128,7 +152,10 @@ class IconEntry extends Entry
return $this->evaluate($this->falseIcon) ?? 'heroicon-o-x-circle';
}
public function getTrueColor(): string
/**
* @return string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string}
*/
public function getTrueColor(): string | array
{
return $this->evaluate($this->trueColor) ?? 'success';
}
+3 -42
View File
@@ -4,10 +4,13 @@ namespace Filament\Infolists\Components\Tabs;
use Closure;
use Filament\Infolists\Components\Component;
use Filament\Support\Concerns\HasIcon;
use Illuminate\Support\Str;
class Tab extends Component
{
use HasIcon;
/**
* @var view-string
*/
@@ -15,12 +18,6 @@ class Tab extends Component
protected string | Closure | null $badge = null;
protected string | Closure | null $icon = null;
protected string | Closure | null $iconPosition = null;
protected string | Closure | null $iconColor = null;
final public function __construct(string $label)
{
$this->label($label);
@@ -35,27 +32,6 @@ class Tab extends Component
return $static;
}
public function icon(string | Closure | null $icon): static
{
$this->icon = $icon;
return $this;
}
public function iconPosition(string | Closure | null $position): static
{
$this->iconPosition = $position;
return $this;
}
public function iconColor(string | Closure | null $color): static
{
$this->iconColor = $color;
return $this;
}
public function badge(string | Closure | null $badge): static
{
$this->badge = $badge;
@@ -76,21 +52,6 @@ class Tab extends Component
return $this->columns ?? $this->getContainer()->getColumnsConfig();
}
public function getIcon(): ?string
{
return $this->evaluate($this->icon);
}
public function getIconPosition(): ?string
{
return $this->evaluate($this->iconPosition) ?? 'before';
}
public function getIconColor(): ?string
{
return $this->evaluate($this->iconColor);
}
public function getBadge(): ?string
{
return $this->evaluate($this->badge);
@@ -1,5 +1,5 @@
@props([
'color' => null,
'color' => 'gray',
'name',
'size' => 'lg',
])
@@ -7,21 +7,20 @@
<x-filament::icon
:name="$name"
alias="notifications::notification"
:color="match ($color) {
'danger' => 'text-danger-400',
'gray', null => 'text-gray-400',
'info' => 'text-info-400',
'primary' => 'text-primary-400',
'secondary' => 'text-secondary-400',
'success' => 'text-success-400',
'warning' => 'text-warning-400',
default => $color,
}"
color="text-custom-400"
:size="match ($size) {
'sm' => 'h-4 w-4',
'md' => 'h-5 w-5',
'lg' => 'h-6 w-6',
default => $size,
}"
class="filament-notifications-notification-icon"
{{-- format-ignore-start --}}
{{
$attributes
->class(['filament-notifications-notification-icon'])
->style([
\Filament\Support\get_color_css_variables($color, shades: [400]),
])
}}
{{-- format-ignore-end --}}
/>
@@ -1,5 +1,5 @@
@php
$color = $getColor();
$color = $getColor() ?? 'gray';
$isInline = $isInline();
@endphp
@@ -27,18 +27,15 @@
false => [
'max-w-sm rounded-xl bg-white shadow-lg ring-1 dark:bg-gray-800',
match ($color) {
'danger' => 'ring-danger-500/50',
'gray' => 'ring-gray-500/50',
'info' => 'ring-info-500/50',
'primary' => 'ring-primary-500/50',
'secondary' => 'ring-secondary-500/50',
'success' => 'ring-success-500/50',
'warning' => 'ring-warning-500/50',
default => 'ring-gray-950/5 dark:ring-white/20',
'gray' => 'ring-gray-950/5 dark:ring-white/20',
default => 'ring-custom-500/50',
},
],
},
])
@style([
\Filament\Support\get_color_css_variables($color, shades: [500]) => ! ($isInline || $color === 'gray'),
])
>
<div
@class([
@@ -48,18 +45,15 @@
false => [
'rounded-xl p-4',
match ($color) {
'danger' => 'bg-danger-500/10 dark:bg-danger-500/20',
'gray' => 'bg-gray-500/10 dark:bg-gray-500/20',
'info' => 'bg-info-500/10 dark:bg-info-500/20',
'primary' => 'bg-primary-500/10 dark:bg-primary-500/20',
'secondary' => 'bg-secondary-500/10 dark:bg-secondary-500/20',
'success' => 'bg-success-500/10 dark:bg-success-500/20',
'warning' => 'bg-warning-500/10 dark:bg-warning-500/20',
default => null,
'gray' => null,
default => 'bg-custom-500/10 dark:bg-custom-500/20',
},
],
},
])
@style([
\Filament\Support\get_color_css_variables($color, shades: [500]) => ! ($isInline || $color === 'gray'),
])
>
@if ($icon = $getIcon())
<x-filament-notifications::icon
@@ -1,22 +0,0 @@
<?php
namespace Filament\Notifications\Concerns;
use Closure;
trait HasColor
{
protected string | Closure | null $color = null;
public function color(string | Closure | null $color): static
{
$this->color = $color;
return $this;
}
public function getColor(): ?string
{
return $this->evaluate($this->color);
}
}
+2 -1
View File
@@ -7,6 +7,7 @@ use Filament\Notifications\Actions\ActionGroup;
use Filament\Notifications\Events\DatabaseNotificationsSent;
use Filament\Notifications\Http\Livewire\Notifications;
use Filament\Support\Components\ViewComponent;
use Filament\Support\Concerns\HasColor;
use Filament\Support\Concerns\HasIcon;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Support\Arrayable;
@@ -23,11 +24,11 @@ class Notification extends ViewComponent implements Arrayable
use Concerns\CanBeInline;
use Concerns\HasActions;
use Concerns\HasBody;
use Concerns\HasColor;
use Concerns\HasDate;
use Concerns\HasDuration;
use Concerns\HasId;
use Concerns\HasTitle;
use HasColor;
use HasIcon;
/**
+3 -3
View File
@@ -8,7 +8,7 @@ In the [configuration](configuration), you can easily change the colors that are
```php
use Filament\Panel;
use Filament\Support\Color;
use Filament\Support\Colors\Color;
public function panel(Panel $panel): Panel
{
@@ -24,7 +24,7 @@ public function panel(Panel $panel): Panel
}
```
The `Filament\Support\Color` class contains color options for all [Tailwind CSS color palettes](https://tailwindcss.com/docs/customizing-colors).
The `Filament\Support\Colors\Color` class contains color options for all [Tailwind CSS color palettes](https://tailwindcss.com/docs/customizing-colors).
Alternatively, you may pass your own palette in as an array of RGB values:
@@ -49,7 +49,7 @@ $panel->primaryColor([
If you want us to attempt to generate a palette for you based on a singular hex or RGB value, you can pass that in:
```php
use Filament\Support\Color;
use Filament\Support\Colors\Color;
$panel->primaryColor('#6366f1')
@@ -1,29 +1,26 @@
@props([
'active' => false,
'badge' => null,
'badgeColor' => null,
'badgeColor' => 'primary',
])
<span
@if (filament()->isSidebarCollapsibleOnDesktop())
x-show="$store.sidebar.isOpen"
@endif
@class([
'min-h-4 ms-auto inline-flex items-center justify-center whitespace-normal rounded-xl px-2 py-0.5 text-xs font-medium tracking-tight',
match ($active) {
true => 'bg-gray-900/10 text-white',
false => match ($badgeColor) {
'danger' => 'bg-danger-500/10 text-danger-700 dark:text-danger-500',
'gray' => 'bg-gray-500/10 text-gray-700 dark:text-gray-500',
'info' => 'bg-info-500/10 text-info-700 dark:text-info-500',
'primary', null => 'bg-primary-500/10 text-primary-700 dark:text-primary-500',
'secondary' => 'bg-secondary-500/10 text-secondary-700 dark:text-secondary-500',
'success' => 'bg-success-500/10 text-success-700 dark:text-success-500',
'warning' => 'bg-warning-500/10 text-warning-700 dark:text-warning-500',
default => $badgeColor,
},
},
])
{{
$attributes
->class([
'min-h-4 ms-auto inline-flex items-center justify-center whitespace-normal rounded-xl px-2 py-0.5 text-xs font-medium tracking-tight',
match ($active) {
true => 'bg-gray-900/10 text-white',
false => 'bg-custom-500/10 text-custom-700 dark:text-custom-500',
},
])
->style([
\Filament\Support\get_color_css_variables($badgeColor, shades: [500, 700]) => ! $active,
])
}}
>
{{ $badge }}
</span>
@@ -4,7 +4,7 @@
'badge' => null,
'badgeColor' => null,
'icon',
'iconColor' => null,
'iconColor' => 'gray',
'shouldOpenUrlInNewTab' => false,
'url',
])
@@ -45,16 +45,11 @@
<x-filament::icon
:name="($active && $activeIcon) ? $activeIcon : $icon"
alias="panels::sidebar.item"
:color="(! $active) ? match ($iconColor) {
'primary' => 'text-primary-600 dark:text-primary-500',
'danger' => 'text-danger-600 dark:text-danger-500',
'info' => 'text-info-600 dark:text-info-500',
'secondary' => 'text-secondary-600 dark:text-secondary-500',
'success' => 'text-success-600 dark:text-success-500',
'warning' => 'text-warning-600 dark:text-warning-500',
default => 'text-gray-600 dark:text-gray-500',
} : null"
:color="$active ? null : 'text-custom-600 dark:text-custom-500'"
size="h-6 w-6"
@style([
\Filament\Support\get_color_css_variables($iconColor, shades: [500, 600]) => ! $active,
])
/>
<div
@@ -1,26 +1,23 @@
@props([
'active' => false,
'badge' => null,
'badgeColor' => null,
'badgeColor' => 'primary',
])
<span
@class([
'min-h-4 ms-auto inline-flex items-center justify-center whitespace-normal rounded-xl px-2 py-0.5 text-xs font-medium tracking-tight',
match ($active) {
true => 'bg-gray-900/10 text-white',
false => match ($badgeColor) {
'danger' => 'bg-danger-500/10 text-danger-700 dark:text-danger-500',
'gray' => 'bg-gray-500/10 text-gray-700 dark:text-gray-500',
'info' => 'bg-info-500/10 text-info-700 dark:text-info-500',
'primary', null => 'bg-primary-500/10 text-primary-700 dark:text-primary-500',
'secondary' => 'bg-secondary-500/10 text-secondary-700 dark:text-secondary-500',
'success' => 'bg-success-500/10 text-success-700 dark:text-success-500',
'warning' => 'bg-warning-500/10 text-warning-700 dark:text-warning-500',
default => $badgeColor,
},
},
])
{{
$attributes
->class([
'min-h-4 ms-auto inline-flex items-center justify-center whitespace-normal rounded-xl px-2 py-0.5 text-xs font-medium tracking-tight',
match ($active) {
true => 'bg-gray-900/10 text-white',
false => 'bg-custom-500/10 text-custom-700 dark:text-custom-500',
},
])
->style([
\Filament\Support\get_color_css_variables($badgeColor, shades: [500, 700]) => ! $active,
])
}}
>
{{ $badge }}
</span>
@@ -59,12 +59,6 @@
--filament-widgets-chart-font-family: var(--font-family);
--sidebar-width: {{ filament()->getSidebarWidth() }};
--collapsed-sidebar-width: {{ filament()->getCollapsedSidebarWidth() }};
@foreach (filament()->getColors() as $key => $palette)
@foreach ($palette as $shade => $color)
--{{ $key }}-color-{{ $shade }}: {{ $color }};
@endforeach
@endforeach
}
</style>
+2 -17
View File
@@ -27,17 +27,8 @@ use Illuminate\Support\Facades\Facade;
* @method static array<NavigationGroup> buildNavigation()
* @method static string getAuthGuard()
* @method static string getBrandName()
* @method static array{
* 'primary': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null,
* 'secondary': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null,
* 'gray': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null,
* 'danger': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null,
* 'warning': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null,
* 'success': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null,
* } getColors()
* @method static string getCollapsedSidebarWidth()
* @method static Panel | null getCurrentPanel()
* @method static array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} getDangerColor()
* @method static string | null getDatabaseNotificationsPollingInterval()
* @method static string getDefaultAvatarProvider()
* @method static Panel getDefaultPanel()
@@ -50,9 +41,7 @@ use Illuminate\Support\Facades\Facade;
* @method static string | null getFontUrl()
* @method static array<string> getGlobalSearchKeyBindings()
* @method static GlobalSearchProvider | null getGlobalSearchProvider()
* @method static array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} getGrayColor()
* @method static string | null getHomeUrl()
* @method static array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} getInfoColor()
* @method static string | null getLoginUrl(array $parameters = [])
* @method static string getLogoutUrl(array $parameters = [])
* @method static string | null getMaxContentWidth()
@@ -61,18 +50,15 @@ use Illuminate\Support\Facades\Facade;
* @method static array<NavigationGroup> getNavigation()
* @method static array<string | int, NavigationGroup | string> getNavigationGroups()
* @method static array<NavigationItem> getNavigationItems()
* @method static array<class-string> getPages()
* @method static array getPages()
* @method static Panel getPanel(?string $id = null)
* @method static array<string, Panel> getPanels()
* @method static Plugin getPlugin(string $id)
* @method static array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} getPrimaryColor()
* @method static string | null getRegistrationUrl(array $parameters = [])
* @method static string | null getRequestPasswordResetUrl(array $parameters = [])
* @method static string getResetPasswordUrl(string $token, CanResetPassword | Model | Authenticatable $user, array $parameters = [])
* @method static array<class-string> getResources()
* @method static array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} getSecondaryColor()
* @method static array getResources()
* @method static string getSidebarWidth()
* @method static array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} getSuccessColor()
* @method static Model | null getTenant()
* @method static string | null getTenantAvatarUrl(Model $tenant)
* @method static BillingProvider | null getTenantBillingProvider()
@@ -91,7 +77,6 @@ use Illuminate\Support\Facades\Facade;
* @method static array<Model> getUserTenants(HasTenants | Model | Authenticatable $user)
* @method static string | null getUrl(Model | null $tenant = null)
* @method static string getVerifyEmailUrl(MustVerifyEmail | Model | Authenticatable $user, array $parameters = [])
* @method static array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} getWarningColor()
* @method static array<class-string> getWidgets()
* @method static bool hasBreadcrumbs()
* @method static bool hasCollapsibleNavigationGroups()
-72
View File
@@ -69,22 +69,6 @@ class FilamentManager
return $this->getCurrentPanel()->getBrandName();
}
/**
* @return array{
* 'danger': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null,
* 'gray': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null,
* 'info': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null,
* 'primary': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null,
* 'secondary': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null,
* 'success': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null,
* 'warning': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null,
* }
*/
public function getColors(): array
{
return $this->getCurrentPanel()->getColors();
}
public function getCollapsedSidebarWidth(): string
{
return $this->getCurrentPanel()->getCollapsedSidebarWidth();
@@ -95,14 +79,6 @@ class FilamentManager
return $this->currentPanel ?? null;
}
/**
* @return array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string}
*/
public function getDangerColor(): array
{
return $this->getCurrentPanel()->getDangerColor();
}
public function getDatabaseNotificationsPollingInterval(): ?string
{
return $this->getCurrentPanel()->getDatabaseNotificationsPollingInterval();
@@ -176,27 +152,11 @@ class FilamentManager
return $this->getCurrentPanel()->getGlobalSearchProvider();
}
/**
* @return array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string}
*/
public function getGrayColor(): array
{
return $this->getCurrentPanel()->getGrayColor();
}
public function getHomeUrl(): ?string
{
return $this->getCurrentPanel()->getHomeUrl() ?? $this->getCurrentPanel()->getUrl();
}
/**
* @return array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string}
*/
public function getInfoColor(): array
{
return $this->getCurrentPanel()->getInfoColor();
}
/**
* @param array<mixed> $parameters
*/
@@ -282,14 +242,6 @@ class FilamentManager
return $this->getCurrentPanel()->getPlugin($id);
}
/**
* @return array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string}
*/
public function getPrimaryColor(): array
{
return $this->getCurrentPanel()->getPrimaryColor();
}
/**
* @param array<mixed> $parameters
*/
@@ -322,27 +274,11 @@ class FilamentManager
return $this->getCurrentPanel()->getResources();
}
/**
* @return array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string}
*/
public function getSecondaryColor(): array
{
return $this->getCurrentPanel()->getSecondaryColor();
}
public function getSidebarWidth(): string
{
return $this->getCurrentPanel()->getSidebarWidth();
}
/**
* @return array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string}
*/
public function getSuccessColor(): array
{
return $this->getCurrentPanel()->getSuccessColor();
}
public function getTenant(): ?Model
{
return $this->tenant;
@@ -498,14 +434,6 @@ class FilamentManager
return $this->getCurrentPanel()->getVerifyEmailUrl($user, $parameters);
}
/**
* @return array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string}
*/
public function getWarningColor(): array
{
return $this->getCurrentPanel()->getWarningColor();
}
/**
* @return array<class-string>
*/
+12 -3
View File
@@ -6,7 +6,10 @@ use Closure;
class MenuItem
{
protected ?string $color = null;
/**
* @var string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null
*/
protected string | array | null $color = null;
protected ?string $icon = null;
@@ -25,7 +28,10 @@ class MenuItem
return app(static::class);
}
public function color(?string $color): static
/**
* @param string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null $color
*/
public function color(string | array | null $color): static
{
$this->color = $color;
@@ -60,7 +66,10 @@ class MenuItem
return $this;
}
public function getColor(): ?string
/**
* @return string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null
*/
public function getColor(): string | array | null
{
return $this->color;
}
@@ -14,13 +14,19 @@ class NavigationItem
protected ?string $activeIcon = null;
protected ?string $iconColor = null;
/**
* @var string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null
*/
protected string | array | null $iconColor = null;
protected string $label;
protected ?string $badge = null;
protected ?string $badgeColor = null;
/**
* @var string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null
*/
protected string | array | null $badgeColor = null;
protected bool $shouldOpenUrlInNewTab = false;
@@ -44,7 +50,10 @@ class NavigationItem
return app(static::class, ['label' => $label]);
}
public function badge(?string $badge, ?string $color = null): static
/**
* @param string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null $color
*/
public function badge(?string $badge, string | array | null $color = null): static
{
$this->badge = $badge;
$this->badgeColor = $color;
@@ -87,9 +96,12 @@ class NavigationItem
return $this;
}
public function iconColor(?string $iconColor): static
/**
* @param string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null $color
*/
public function iconColor(string | array | null $color): static
{
$this->iconColor = $iconColor;
$this->iconColor = $color;
return $this;
}
@@ -135,7 +147,10 @@ class NavigationItem
return $this->badge;
}
public function getBadgeColor(): ?string
/**
* @return string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null
*/
public function getBadgeColor(): string | array | null
{
return $this->badgeColor;
}
@@ -169,7 +184,10 @@ class NavigationItem
return $this->activeIcon;
}
public function getIconColor(): ?string
/**
* @return string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null
*/
public function getIconColor(): string | array | null
{
return $this->iconColor;
}
+4 -1
View File
@@ -116,7 +116,10 @@ abstract class Page extends BasePage
return null;
}
public static function getNavigationBadgeColor(): ?string
/**
* @return string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null
*/
public static function getNavigationBadgeColor(): string | array | null
{
return null;
}
+3
View File
@@ -4,6 +4,7 @@ namespace Filament;
use Closure;
use Filament\Support\Components\Component;
use Filament\Support\Facades\FilamentColor;
use Filament\Support\Facades\FilamentIcon;
class Panel extends Component
@@ -46,6 +47,8 @@ class Panel extends Component
public function boot(): void
{
FilamentColor::register($this->colors);
FilamentIcon::register($this->icons);
$this->registerLivewireComponents();
@@ -2,209 +2,22 @@
namespace Filament\Panel\Concerns;
use Filament\Support\Color;
trait HasColors
{
/**
* @var array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null
* @var array<string, array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | string>
*/
protected ?array $dangerColor = null;
protected array $colors = [];
/**
* @var array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null
* @param array<string, array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | string> $colors
*/
protected ?array $grayColor = null;
/**
* @var array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null
*/
protected ?array $infoColor = null;
/**
* @var array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null
*/
protected ?array $primaryColor = null;
/**
* @var array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null
*/
protected ?array $secondaryColor = null;
/**
* @var array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null
*/
protected ?array $successColor = null;
/**
* @var array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null
*/
protected ?array $warningColor = null;
/**
* @param array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | string $color
* @return array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | string
*/
public function processColor(array | string $color): array | string
public function colors(array $colors): static
{
if (is_string($color) && str_starts_with($color, '#')) {
return Color::hex($color);
foreach ($colors as $name => $color) {
$this->colors[$name] = $color;
}
if (is_string($color) && str_starts_with($color, 'rgb')) {
return Color::rgb($color);
}
return $color;
}
/**
* @param array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | string | null $color
*/
public function dangerColor(array | string | null $color): static
{
$this->dangerColor = $this->processColor($color);
return $this;
}
/**
* @return array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string}
*/
public function getDangerColor(): array
{
return $this->dangerColor ?? Color::Red;
}
/**
* @param array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | string | null $color
*/
public function grayColor(array | string | null $color): static
{
$this->grayColor = $this->processColor($color);
return $this;
}
/**
* @return array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string}
*/
public function getGrayColor(): array
{
return $this->grayColor ?? Color::Gray;
}
/**
* @param array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | string | null $color
*/
public function infoColor(array | string | null $color): static
{
$this->infoColor = $this->processColor($color);
return $this;
}
/**
* @return array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string}
*/
public function getInfoColor(): array
{
return $this->infoColor ?? Color::Blue;
}
/**
* @param array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | string | null $color
*/
public function primaryColor(array | string | null $color): static
{
$this->primaryColor = $this->processColor($color);
return $this;
}
/**
* @return array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string}
*/
public function getPrimaryColor(): array
{
return $this->primaryColor ?? Color::Amber;
}
/**
* @param array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | string | null $color
*/
public function secondaryColor(array | string | null $color): static
{
$this->secondaryColor = $this->processColor($color);
return $this;
}
/**
* @return array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string}
*/
public function getSecondaryColor(): array
{
return $this->secondaryColor ?? Color::Gray;
}
/**
* @param array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | string | null $color
*/
public function successColor(array | string | null $color): static
{
$this->successColor = $this->processColor($color);
return $this;
}
/**
* @return array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string}
*/
public function getSuccessColor(): array
{
return $this->successColor ?? Color::Green;
}
/**
* @param array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | string | null $color
*/
public function warningColor(array | string | null $color): static
{
$this->warningColor = $this->processColor($color);
return $this;
}
/**
* @return array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string}
*/
public function getWarningColor(): array
{
return $this->warningColor ?? Color::Amber;
}
/**
* @return array{
* 'danger': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null,
* 'gray': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null,
* 'info': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null,
* 'primary': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null,
* 'secondary': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null,
* 'success': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null,
* 'warning': array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null,
* }
*/
public function getColors(): array
{
return [
'danger' => $this->getDangerColor(),
'gray' => $this->getGrayColor(),
'info' => $this->getInfoColor(),
'primary' => $this->getPrimaryColor(),
'secondary' => $this->getSecondaryColor(),
'success' => $this->getSuccessColor(),
'warning' => $this->getWarningColor(),
];
}
}
@@ -4,18 +4,15 @@ namespace Filament\Resources\Pages\ListRecords;
use Closure;
use Filament\Support\Components\Component;
use Filament\Support\Concerns\HasIcon;
use Illuminate\Database\Eloquent\Builder;
class Tab extends Component
{
use HasIcon;
protected string | Closure | null $label = null;
protected string | Closure | null $icon = null;
protected string | Closure | null $iconPosition = null;
protected string | Closure | null $iconColor = null;
protected string | Closure | null $badge = null;
protected ?Closure $modifyQueryUsing = null;
@@ -40,27 +37,6 @@ class Tab extends Component
return $this;
}
public function icon(string | Closure | null $icon): static
{
$this->icon = $icon;
return $this;
}
public function iconPosition(string | Closure | null $position): static
{
$this->iconPosition = $position;
return $this;
}
public function iconColor(string | Closure | null $color): static
{
$this->iconColor = $color;
return $this;
}
public function label(string | Closure | null $label): static
{
$this->label = $label;
@@ -92,21 +68,6 @@ class Tab extends Component
return $this->evaluate($this->badge);
}
public function getIcon(): ?string
{
return $this->evaluate($this->icon);
}
public function getIconPosition(): ?string
{
return $this->evaluate($this->iconPosition) ?? 'before';
}
public function getIconColor(): ?string
{
return $this->evaluate($this->iconColor);
}
public function modifyQuery(Builder $query): Builder
{
return $this->evaluate($this->modifyQueryUsing, [
@@ -4,15 +4,12 @@ namespace Filament\Resources\RelationManagers;
use Closure;
use Filament\Support\Components\Component;
use Filament\Support\Concerns\HasIcon;
use Illuminate\Database\Eloquent\Model;
class RelationGroup extends Component
{
protected string | Closure | null $icon = null;
protected string | Closure | null $iconPosition = null;
protected string | Closure | null $iconColor = null;
use HasIcon;
protected string | Closure | null $badge = null;
@@ -61,27 +58,6 @@ class RelationGroup extends Component
return $this;
}
public function icon(string | Closure | null $icon): static
{
$this->icon = $icon;
return $this;
}
public function iconPosition(string | Closure | null $position): static
{
$this->iconPosition = $position;
return $this;
}
public function iconColor(string | Closure | null $color): static
{
$this->iconColor = $color;
return $this;
}
public function getLabel(): string
{
return $this->evaluate($this->label);
@@ -110,21 +86,6 @@ class RelationGroup extends Component
return $this->evaluate($this->badge);
}
public function getIcon(): ?string
{
return $this->evaluate($this->icon);
}
public function getIconPosition(): ?string
{
return $this->evaluate($this->iconPosition) ?? 'before';
}
public function getIconColor(): ?string
{
return $this->evaluate($this->iconColor);
}
public function getOwnerRecord(): ?Model
{
return $this->ownerRecord;
@@ -39,7 +39,10 @@ class RelationManager extends Component implements Forms\Contracts\HasForms, Tab
protected static ?string $icon = null;
protected static ?string $iconColor = null;
/**
* @var string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null
*/
protected static string | array | null $iconColor = null;
protected static ?string $iconPosition = 'before';
@@ -327,7 +330,10 @@ class RelationManager extends Component implements Forms\Contracts\HasForms, Tab
return static::$icon;
}
public static function getIconColor(Model $ownerRecord, string $pageClass): ?string
/**
* @return string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null
*/
public static function getIconColor(Model $ownerRecord, string $pageClass): string | array | null
{
return static::$iconColor;
}
+4 -1
View File
@@ -633,7 +633,10 @@ abstract class Resource
return null;
}
public static function getNavigationBadgeColor(): ?string
/**
* @return string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null
*/
public static function getNavigationBadgeColor(): string | array | null
{
return null;
}
+4 -2
View File
@@ -8,7 +8,7 @@ use Filament\Http\Middleware\DispatchServingFilamentEvent;
use Filament\Pages;
use Filament\Panel;
use Filament\PanelProvider;
use Filament\Support\Color;
use Filament\Support\Colors\Color;
use Filament\Widgets;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use Illuminate\Cookie\Middleware\EncryptCookies;
@@ -25,7 +25,9 @@ class {{ class }} extends PanelProvider
return $panel
->id('{{ id }}')
->path('{{ id }}')
->primaryColor(Color::Amber)
->colors([
'primary' => Color::Amber,
])
->discoverResources(in: app_path('Filament/{{ directory }}/Resources'), for: 'App\\Filament\\{{ directory }}\\Resources')
->discoverPages(in: app_path('Filament/{{ directory }}/Pages'), for: 'App\\Filament\\{{ directory }}\\Pages')
->pages([
+90 -77
View File
@@ -8,96 +8,109 @@ export default {
theme: {
extend: {
colors: {
custom: {
50: 'rgba(var(--c-50), <alpha-value>)',
100: 'rgba(var(--c-100), <alpha-value>)',
200: 'rgba(var(--c-200), <alpha-value>)',
300: 'rgba(var(--c-300), <alpha-value>)',
400: 'rgba(var(--c-400), <alpha-value>)',
500: 'rgba(var(--c-500), <alpha-value>)',
600: 'rgba(var(--c-600), <alpha-value>)',
700: 'rgba(var(--c-700), <alpha-value>)',
800: 'rgba(var(--c-800), <alpha-value>)',
900: 'rgba(var(--c-900), <alpha-value>)',
950: 'rgba(var(--c-950), <alpha-value>)',
},
danger: {
50: 'rgba(var(--danger-color-50), <alpha-value>)',
100: 'rgba(var(--danger-color-100), <alpha-value>)',
200: 'rgba(var(--danger-color-200), <alpha-value>)',
300: 'rgba(var(--danger-color-300), <alpha-value>)',
400: 'rgba(var(--danger-color-400), <alpha-value>)',
500: 'rgba(var(--danger-color-500), <alpha-value>)',
600: 'rgba(var(--danger-color-600), <alpha-value>)',
700: 'rgba(var(--danger-color-700), <alpha-value>)',
800: 'rgba(var(--danger-color-800), <alpha-value>)',
900: 'rgba(var(--danger-color-900), <alpha-value>)',
950: 'rgba(var(--danger-color-950), <alpha-value>)',
50: 'rgba(var(--danger-50), <alpha-value>)',
100: 'rgba(var(--danger-100), <alpha-value>)',
200: 'rgba(var(--danger-200), <alpha-value>)',
300: 'rgba(var(--danger-300), <alpha-value>)',
400: 'rgba(var(--danger-400), <alpha-value>)',
500: 'rgba(var(--danger-500), <alpha-value>)',
600: 'rgba(var(--danger-600), <alpha-value>)',
700: 'rgba(var(--danger-700), <alpha-value>)',
800: 'rgba(var(--danger-800), <alpha-value>)',
900: 'rgba(var(--danger-900), <alpha-value>)',
950: 'rgba(var(--danger-950), <alpha-value>)',
},
gray: {
50: 'rgba(var(--gray-color-50), <alpha-value>)',
100: 'rgba(var(--gray-color-100), <alpha-value>)',
200: 'rgba(var(--gray-color-200), <alpha-value>)',
300: 'rgba(var(--gray-color-300), <alpha-value>)',
400: 'rgba(var(--gray-color-400), <alpha-value>)',
500: 'rgba(var(--gray-color-500), <alpha-value>)',
600: 'rgba(var(--gray-color-600), <alpha-value>)',
700: 'rgba(var(--gray-color-700), <alpha-value>)',
800: 'rgba(var(--gray-color-800), <alpha-value>)',
900: 'rgba(var(--gray-color-900), <alpha-value>)',
950: 'rgba(var(--gray-color-950), <alpha-value>)',
50: 'rgba(var(--gray-50), <alpha-value>)',
100: 'rgba(var(--gray-100), <alpha-value>)',
200: 'rgba(var(--gray-200), <alpha-value>)',
300: 'rgba(var(--gray-300), <alpha-value>)',
400: 'rgba(var(--gray-400), <alpha-value>)',
500: 'rgba(var(--gray-500), <alpha-value>)',
600: 'rgba(var(--gray-600), <alpha-value>)',
700: 'rgba(var(--gray-700), <alpha-value>)',
800: 'rgba(var(--gray-800), <alpha-value>)',
900: 'rgba(var(--gray-900), <alpha-value>)',
950: 'rgba(var(--gray-950), <alpha-value>)',
},
info: {
50: 'rgba(var(--info-color-50), <alpha-value>)',
100: 'rgba(var(--info-color-100), <alpha-value>)',
200: 'rgba(var(--info-color-200), <alpha-value>)',
300: 'rgba(var(--info-color-300), <alpha-value>)',
400: 'rgba(var(--info-color-400), <alpha-value>)',
500: 'rgba(var(--info-color-500), <alpha-value>)',
600: 'rgba(var(--info-color-600), <alpha-value>)',
700: 'rgba(var(--info-color-700), <alpha-value>)',
800: 'rgba(var(--info-color-800), <alpha-value>)',
900: 'rgba(var(--info-color-900), <alpha-value>)',
950: 'rgba(var(--info-color-950), <alpha-value>)',
50: 'rgba(var(--info-50), <alpha-value>)',
100: 'rgba(var(--info-100), <alpha-value>)',
200: 'rgba(var(--info-200), <alpha-value>)',
300: 'rgba(var(--info-300), <alpha-value>)',
400: 'rgba(var(--info-400), <alpha-value>)',
500: 'rgba(var(--info-500), <alpha-value>)',
600: 'rgba(var(--info-600), <alpha-value>)',
700: 'rgba(var(--info-700), <alpha-value>)',
800: 'rgba(var(--info-800), <alpha-value>)',
900: 'rgba(var(--info-900), <alpha-value>)',
950: 'rgba(var(--info-950), <alpha-value>)',
},
primary: {
50: 'rgba(var(--primary-color-50), <alpha-value>)',
100: 'rgba(var(--primary-color-100), <alpha-value>)',
200: 'rgba(var(--primary-color-200), <alpha-value>)',
300: 'rgba(var(--primary-color-300), <alpha-value>)',
400: 'rgba(var(--primary-color-400), <alpha-value>)',
500: 'rgba(var(--primary-color-500), <alpha-value>)',
600: 'rgba(var(--primary-color-600), <alpha-value>)',
700: 'rgba(var(--primary-color-700), <alpha-value>)',
800: 'rgba(var(--primary-color-800), <alpha-value>)',
900: 'rgba(var(--primary-color-900), <alpha-value>)',
950: 'rgba(var(--primary-color-950), <alpha-value>)',
50: 'rgba(var(--primary-50), <alpha-value>)',
100: 'rgba(var(--primary-100), <alpha-value>)',
200: 'rgba(var(--primary-200), <alpha-value>)',
300: 'rgba(var(--primary-300), <alpha-value>)',
400: 'rgba(var(--primary-400), <alpha-value>)',
500: 'rgba(var(--primary-500), <alpha-value>)',
600: 'rgba(var(--primary-600), <alpha-value>)',
700: 'rgba(var(--primary-700), <alpha-value>)',
800: 'rgba(var(--primary-800), <alpha-value>)',
900: 'rgba(var(--primary-900), <alpha-value>)',
950: 'rgba(var(--primary-950), <alpha-value>)',
},
secondary: {
50: 'rgba(var(--secondary-color-50), <alpha-value>)',
100: 'rgba(var(--secondary-color-100), <alpha-value>)',
200: 'rgba(var(--secondary-color-200), <alpha-value>)',
300: 'rgba(var(--secondary-color-300), <alpha-value>)',
400: 'rgba(var(--secondary-color-400), <alpha-value>)',
500: 'rgba(var(--secondary-color-500), <alpha-value>)',
600: 'rgba(var(--secondary-color-600), <alpha-value>)',
700: 'rgba(var(--secondary-color-700), <alpha-value>)',
800: 'rgba(var(--secondary-color-800), <alpha-value>)',
900: 'rgba(var(--secondary-color-900), <alpha-value>)',
950: 'rgba(var(--secondary-color-950), <alpha-value>)',
50: 'rgba(var(--secondary-50), <alpha-value>)',
100: 'rgba(var(--secondary-100), <alpha-value>)',
200: 'rgba(var(--secondary-200), <alpha-value>)',
300: 'rgba(var(--secondary-300), <alpha-value>)',
400: 'rgba(var(--secondary-400), <alpha-value>)',
500: 'rgba(var(--secondary-500), <alpha-value>)',
600: 'rgba(var(--secondary-600), <alpha-value>)',
700: 'rgba(var(--secondary-700), <alpha-value>)',
800: 'rgba(var(--secondary-800), <alpha-value>)',
900: 'rgba(var(--secondary-900), <alpha-value>)',
950: 'rgba(var(--secondary-950), <alpha-value>)',
},
success: {
50: 'rgba(var(--success-color-50), <alpha-value>)',
100: 'rgba(var(--success-color-100), <alpha-value>)',
200: 'rgba(var(--success-color-200), <alpha-value>)',
300: 'rgba(var(--success-color-300), <alpha-value>)',
400: 'rgba(var(--success-color-400), <alpha-value>)',
500: 'rgba(var(--success-color-500), <alpha-value>)',
600: 'rgba(var(--success-color-600), <alpha-value>)',
700: 'rgba(var(--success-color-700), <alpha-value>)',
800: 'rgba(var(--success-color-800), <alpha-value>)',
900: 'rgba(var(--success-color-900), <alpha-value>)',
950: 'rgba(var(--success-color-950), <alpha-value>)',
50: 'rgba(var(--success-50), <alpha-value>)',
100: 'rgba(var(--success-100), <alpha-value>)',
200: 'rgba(var(--success-200), <alpha-value>)',
300: 'rgba(var(--success-300), <alpha-value>)',
400: 'rgba(var(--success-400), <alpha-value>)',
500: 'rgba(var(--success-500), <alpha-value>)',
600: 'rgba(var(--success-600), <alpha-value>)',
700: 'rgba(var(--success-700), <alpha-value>)',
800: 'rgba(var(--success-800), <alpha-value>)',
900: 'rgba(var(--success-900), <alpha-value>)',
950: 'rgba(var(--success-950), <alpha-value>)',
},
warning: {
50: 'rgba(var(--warning-color-50), <alpha-value>)',
100: 'rgba(var(--warning-color-100), <alpha-value>)',
200: 'rgba(var(--warning-color-200), <alpha-value>)',
300: 'rgba(var(--warning-color-300), <alpha-value>)',
400: 'rgba(var(--warning-color-400), <alpha-value>)',
500: 'rgba(var(--warning-color-500), <alpha-value>)',
600: 'rgba(var(--warning-color-600), <alpha-value>)',
700: 'rgba(var(--warning-color-700), <alpha-value>)',
800: 'rgba(var(--warning-color-800), <alpha-value>)',
900: 'rgba(var(--warning-color-900), <alpha-value>)',
950: 'rgba(var(--warning-color-950), <alpha-value>)',
50: 'rgba(var(--warning-50), <alpha-value>)',
100: 'rgba(var(--warning-100), <alpha-value>)',
200: 'rgba(var(--warning-200), <alpha-value>)',
300: 'rgba(var(--warning-300), <alpha-value>)',
400: 'rgba(var(--warning-400), <alpha-value>)',
500: 'rgba(var(--warning-500), <alpha-value>)',
600: 'rgba(var(--warning-600), <alpha-value>)',
700: 'rgba(var(--warning-700), <alpha-value>)',
800: 'rgba(var(--warning-800), <alpha-value>)',
900: 'rgba(var(--warning-900), <alpha-value>)',
950: 'rgba(var(--warning-950), <alpha-value>)',
},
},
fontFamily: {
@@ -7,3 +7,9 @@
@foreach ($assets as $asset)
{{ $asset->getHtml() }}
@endforeach
<style>
:root {
@foreach ($cssVariables ?? [] as $cssVariableName => $cssVariableValue) --{{ $cssVariableName }}:{{ $cssVariableValue }}; @endforeach
}
</style>
@@ -18,9 +18,10 @@
])
@php
$buttonClasses = [
$buttonClasses = \Illuminate\Support\Arr::toCssClasses([
...[
'filament-button relative grid-flow-col items-center justify-center rounded-lg border font-medium outline-none transition-colors focus:ring-2 disabled:pointer-events-none disabled:opacity-70',
is_string($color) ? "filament-button-color-{$color}" : null,
match ($size) {
'xs' => 'filament-button-size-xs gap-1.5 px-[calc(theme(spacing.3)-1px)] py-[calc(theme(spacing.2)-1px)] text-xs',
'sm' => 'filament-button-size-sm gap-1.5 px-[calc(theme(spacing.[3.5])-1px)] py-[calc(theme(spacing.2)-1px)] text-sm',
@@ -43,31 +44,26 @@
? [
'filament-button-outlined',
match ($color) {
'danger' => 'filament-button-color-danger border-danger-600 text-danger-600 hover:bg-danger-500/10 focus:bg-danger-500/10 focus:ring-danger-500/50 dark:border-danger-400 dark:text-danger-400',
'gray' => 'filament-button-color-gray border-gray-300 text-gray-700 hover:bg-gray-500/10 focus:bg-gray-500/10 focus:ring-primary-500/50 dark:border-gray-600 dark:text-gray-200',
'info' => 'filament-button-color-info border-info-600 text-info-600 hover:bg-info-500/10 focus:bg-info-500/10 focus:ring-info-500/50 dark:border-info-400 dark:text-info-400',
'primary' => 'filament-button-color-primary border-primary-600 text-primary-600 hover:bg-primary-500/10 focus:bg-primary-500/10 focus:ring-primary-500/50 dark:border-primary-400 dark:text-primary-400',
'secondary' => 'filament-button-color-secondary border-secondary-600 text-secondary-600 hover:bg-secondary-500/10 focus:bg-secondary-500/10 focus:ring-secondary-500/50 dark:border-secondary-400 dark:text-secondary-400',
'success' => 'filament-button-color-success border-success-600 text-success-600 hover:bg-success-500/10 focus:bg-success-500/10 focus:ring-success-500/50 dark:border-success-400 dark:text-success-400',
'warning' => 'filament-button-color-warning border-warning-600 text-warning-600 hover:bg-warning-500/10 focus:bg-warning-500/10 focus:ring-warning-500/50 dark:border-warning-400 dark:text-warning-400',
default => $color,
'gray' => 'border-gray-300 text-gray-700 hover:bg-gray-500/10 focus:bg-gray-500/10 focus:ring-primary-500/50 dark:border-gray-600 dark:text-gray-200',
default => 'border-custom-600 text-custom-600 hover:bg-custom-500/10 focus:bg-custom-500/10 focus:ring-custom-500/50 dark:border-custom-400 dark:text-custom-400',
},
]
: [
'shadow',
match ($color) {
'danger' => 'filament-button-color-danger border-transparent bg-danger-600 text-white hover:bg-danger-500 focus:bg-danger-500 focus:ring-danger-500/50',
'gray' => 'filament-button-color-gray border-gray-300 bg-white text-gray-700 hover:bg-gray-50 focus:border-transparent focus:bg-gray-50 focus:ring-primary-500 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700 dark:focus:bg-gray-700',
'info' => 'filament-button-color-info border-transparent bg-info-600 text-white hover:bg-info-500 focus:bg-info-500 focus:ring-info-500/50',
'primary' => 'filament-button-color-primary border-transparent bg-primary-600 text-white hover:bg-primary-500 focus:bg-primary-500 focus:ring-primary-500/50',
'secondary' => 'filament-button-color-secondary border-transparent bg-secondary-600 text-white hover:bg-secondary-500 focus:bg-secondary-500 focus:ring-secondary-500/50',
'success' => 'filament-button-color-success border-transparent bg-success-600 text-white hover:bg-success-500 focus:bg-success-500 focus:ring-success-500/50',
'warning' => 'filament-button-color-warning border-transparent bg-warning-600 text-white hover:bg-warning-500 focus:bg-warning-500 focus:ring-warning-500/50',
default => $color,
'gray' => 'border-gray-300 bg-white text-gray-700 hover:bg-gray-50 focus:border-transparent focus:bg-gray-50 focus:ring-primary-500 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700 dark:focus:bg-gray-700',
default => 'border-transparent bg-custom-600 text-white hover:bg-custom-500 focus:bg-custom-500 focus:ring-custom-500/50',
},
]
),
];
]);
$buttonStyles = \Illuminate\Support\Arr::toCssStyles([
\Filament\Support\get_color_css_variables(
$color,
shades: $outlined ? [400, 500, 600] : [500, 600],
) => $color !== 'gray',
]);
$iconSize ??= match ($size) {
'xs', 'sm' => 'sm',
@@ -105,19 +101,9 @@
} => ! $labelSrOnly,
]);
$indicatorClasses = \Illuminate\Support\Arr::toCssClasses([
'filament-button-indicator absolute -top-1 -end-1 inline-flex items-center justify-center h-4 w-4 rounded-full text-[0.5rem] font-medium text-white',
match ($indicatorColor) {
'danger' => 'bg-danger-600',
'gray' => 'bg-gray-600',
'info' => 'bg-info-600',
'primary' => 'bg-primary-600',
'secondary' => 'bg-secondary-600',
'success' => 'bg-success-600',
'warning' => 'bg-warning-600',
default => $indicatorColor,
},
]);
$indicatorClasses = 'filament-button-indicator absolute -end-1 -top-1 inline-flex h-4 w-4 items-center justify-center rounded-full bg-custom-600 text-[0.5rem] font-medium text-white';
$indicatorStyles = \Filament\Support\get_color_css_variables($indicatorColor, shades: [600]);
$labelClasses = \Illuminate\Support\Arr::toCssClasses([
'filament-button-label truncate',
@@ -199,7 +185,8 @@
'wire:target' => ($hasLoadingIndicator && $loadingIndicatorTarget) ? $loadingIndicatorTarget : null,
'x-bind:disabled' => $hasFileUploadLoadingIndicator ? 'isUploadingFile' : false,
], escape: false)
->class($buttonClasses)
->class([$buttonClasses])
->style([$buttonStyles])
}}
>
@if ($iconPosition === 'before')
@@ -276,7 +263,10 @@
@endif
@if ($indicator)
<span class="{{ $indicatorClasses }}">
<span
class="{{ $indicatorClasses }}"
style="{{ $indicatorStyles }}"
>
{{ $indicator }}
</span>
@endif
@@ -292,7 +282,11 @@
@if ($tooltip)
x-tooltip.raw="{{ $tooltip }}"
@endif
{{ $attributes->class($buttonClasses) }}
{{
$attributes
->class([$buttonClasses])
->style([$buttonStyles])
}}
>
@if ($icon && $iconPosition === 'before')
<x-filament::icon
@@ -317,7 +311,10 @@
@endif
@if ($indicator)
<span class="{{ $indicatorClasses }}">
<span
class="{{ $indicatorClasses }}"
style="{{ $indicatorStyles }}"
>
{{ $indicator }}
</span>
@endif
@@ -1,24 +1,23 @@
@props([
'color' => 'primary',
'color' => 'gray',
'icon' => null,
'tag' => 'div',
])
<{{ $tag }}
{{
$attributes->class([
'filament-dropdown-header flex w-full gap-2 p-3 text-sm',
match ($color) {
'danger' => 'filament-dropdown-header-color-danger text-danger-600 dark:text-danger-400',
'gray' => 'filament-dropdown-header-color-gray text-gray-700 dark:text-gray-200',
'info' => 'filament-dropdown-header-color-info text-info-600 dark:text-info-400',
'primary' => 'filament-dropdown-header-color-primary text-primary-600 dark:text-primary-400',
'secondary' => 'filament-dropdown-header-color-secondary text-secondary-600 dark:text-secondary-400',
'success' => 'filament-dropdown-header-color-success text-success-600 dark:text-success-400',
'warning' => 'filament-dropdown-header-color-warning text-warning-600 dark:text-warning-400',
default => $color,
},
])
$attributes
->class([
'filament-dropdown-header flex w-full gap-2 p-3 text-sm',
is_string($color) ? "filament-dropdown-header-color-{$color}" : null,
match ($color) {
'gray' => 'text-gray-700 dark:text-gray-200',
default => 'text-custom-600 dark:text-custom-400',
},
])
->style([
\Filament\Support\get_color_css_variables($color, shades: [400, 600]) => $color !== 'gray',
])
}}
>
@if ($icon)
@@ -1,5 +1,5 @@
@props([
'color' => 'primary',
'color' => 'gray',
'detail' => null,
'disabled' => false,
'icon' => null,
@@ -12,18 +12,17 @@
@php
$buttonClasses = \Illuminate\Support\Arr::toCssClasses([
'filament-dropdown-list-item flex w-full items-center gap-2 whitespace-nowrap rounded-md p-2 text-sm transition-colors outline-none disabled:pointer-events-none disabled:opacity-70',
is_string($color) ? "filament-dropdown-list-item-color-{$color}" : null,
match ($color) {
'danger' => 'filament-dropdown-list-item-color-danger text-danger-600 hover:bg-danger-500/10 focus:bg-danger-500/10 dark:text-danger-400',
'gray' => 'filament-dropdown-list-item-color-gray text-gray-700 hover:bg-gray-500/10 focus:bg-gray-500/10 dark:text-gray-200',
'info' => 'filament-dropdown-list-item-color-info text-info-600 hover:bg-info-500/10 focus:bg-info-500/10 dark:text-info-400',
'primary' => 'filament-dropdown-list-item-color-primary text-primary-600 hover:bg-primary-500/10 focus:bg-primary-500/10 dark:text-primary-400',
'secondary' => 'filament-dropdown-list-item-color-secondary text-secondary-600 hover:bg-secondary-500/10 focus:bg-secondary-500/10 dark:text-secondary-400',
'success' => 'filament-dropdown-list-item-color-success text-success-600 hover:bg-success-500/10 focus:bg-success-500/10 dark:text-success-400',
'warning' => 'filament-dropdown-list-item-color-warning text-warning-600 hover:bg-warning-500/10 focus:bg-warning-500/10 dark:text-warning-400',
default => $color,
default => 'filament-dropdown-list-item-color-custom text-custom-600 hover:bg-custom-500/10 focus:bg-custom-500/10 dark:text-custom-400',
},
]);
$buttonStyles = \Illuminate\Support\Arr::toCssStyles([
\Filament\Support\get_color_css_variables($color, shades: [400, 500, 600]) => $color !== 'gray',
]);
$iconSize = match ($iconSize) {
'sm' => 'h-4 w-4',
'md' => 'h-5 w-5',
@@ -63,6 +62,7 @@
'wire:target' => ($hasLoadingIndicator && $loadingIndicatorTarget) ? $loadingIndicatorTarget : null,
], escape: false)
->class([$buttonClasses])
->style([$buttonStyles])
}}
>
@if ($icon)
@@ -107,7 +107,11 @@
x-data="{}"
x-mousetrap.global.{{ collect($keyBindings)->map(fn (string $keyBinding): string => str_replace('+', '-', $keyBinding))->implode('.') }}
@endif
{{ $attributes->class([$buttonClasses]) }}
{{
$attributes
->class([$buttonClasses])
->style([$buttonStyles])
}}
>
@if ($icon)
<x-filament::icon
@@ -151,6 +155,7 @@
$attributes
->except(['action', 'class', 'method', 'wire:submit'])
->class([$buttonClasses])
->style([$buttonStyles])
}}
>
@if ($icon)
@@ -19,29 +19,9 @@
@php
$iconSize ??= $size;
$buttonClasses = [
'filament-icon-button relative flex items-center justify-center outline-none transition disabled:pointer-events-none disabled:opacity-70',
'rounded-full hover:bg-gray-500/5 dark:hover:bg-gray-300/5' => ! $inline,
match ($color) {
'danger' => 'text-danger-500',
'gray' => 'text-gray-500',
'info' => 'text-info-500',
'primary' => 'text-primary-500',
'secondary' => 'text-secondary-500 dark:text-gray-400',
'success' => 'text-success-500',
'warning' => 'text-warning-500',
default => $color,
},
match ($color) {
'danger' => 'focus:bg-danger-500/10',
'gray' => 'focus:bg-gray-500/10',
'info' => 'focus:bg-info-500/10',
'primary' => 'focus:bg-primary-500/10',
'secondary' => 'focus:bg-secondary-500/10',
'success' => 'focus:bg-success-500/10',
'warning' => 'focus:bg-warning-500/10',
default => $color,
} => ! $inline,
$buttonClasses = \Illuminate\Support\Arr::toCssClasses([
'filament-icon-button relative flex items-center justify-center text-custom-500 outline-none transition disabled:pointer-events-none disabled:opacity-70',
'rounded-full hover:bg-gray-500/5 focus:bg-custom-500/10 dark:hover:bg-gray-300/5' => ! $inline,
match ($size) {
'sm' => 'h-8 w-8',
'sm md:md' => 'h-8 w-8 md:h-10 md:w-10',
@@ -49,7 +29,9 @@
'lg' => 'h-12 w-12',
default => $size,
},
];
]);
$buttonStyles = \Filament\Support\get_color_css_variables($color, shades: [500]);
$iconSize = match ($iconSize) {
'sm' => 'h-4 w-4',
@@ -61,19 +43,9 @@
$iconClasses = 'filament-icon-button-icon';
$indicatorClasses = \Illuminate\Support\Arr::toCssClasses([
'filament-icon-button-indicator absolute -top-0.5 -end-0.5 inline-flex items-center justify-center h-4 w-4 rounded-full text-[0.5rem] font-medium text-white',
match ($indicatorColor) {
'danger' => 'bg-danger-600',
'gray' => 'bg-gray-600',
'info' => 'bg-info-600',
'primary' => 'bg-primary-600',
'secondary' => 'bg-secondary-600',
'success' => 'bg-success-600',
'warning' => 'bg-warning-600',
default => $indicatorColor,
},
]);
$indicatorClasses = 'filament-icon-button-indicator absolute -end-0.5 -top-0.5 inline-flex h-4 w-4 items-center justify-center rounded-full bg-custom-600 text-[0.5rem] font-medium text-white';
$indicatorStyles = \Filament\Support\get_color_css_variables($indicatorColor, shades: [600]);
$wireTarget = $attributes->whereStartsWith(['wire:target', 'wire:click'])->first();
@@ -102,7 +74,8 @@
'title' => $label,
'type' => $type,
], escape: false)
->class($buttonClasses)
->class([$buttonClasses])
->style([$buttonStyles])
}}
>
@if ($label)
@@ -130,7 +103,10 @@
@endif
@if ($indicator)
<span class="{{ $indicatorClasses }}">
<span
class="{{ $indicatorClasses }}"
styles="{{ $indicatorStyles }}"
>
{{ $indicator }}
</span>
@endif
@@ -151,7 +127,8 @@
->merge([
'title' => $label,
], escape: false)
->class($buttonClasses)
->class([$buttonClasses])
->style([$buttonStyles])
}}
>
@if ($label)
@@ -168,7 +145,10 @@
/>
@if ($indicator)
<span class="{{ $indicatorClasses }}">
<span
class="{{ $indicatorClasses }}"
styles="{{ $indicatorStyles }}"
>
{{ $indicator }}
</span>
@endif
@@ -17,26 +17,24 @@
@php
$iconSize ??= $size;
$linkClasses = [
$linkClasses = \Illuminate\Support\Arr::toCssClasses([
'filament-link relative inline-flex items-center justify-center gap-0.5 font-medium outline-none hover:underline focus:underline disabled:pointer-events-none disabled:opacity-70',
'pe-4' => $indicator,
'pointer-events-none opacity-70' => $disabled,
match ($color) {
'danger' => 'text-danger-600 hover:text-danger-500 dark:text-danger-500 dark:hover:text-danger-400',
'gray' => 'text-gray-600 hover:text-gray-500 dark:text-gray-300 dark:hover:text-gray-200',
'info' => 'text-info-600 hover:text-info-500 dark:text-info-500 dark:hover:text-info-400',
'primary' => 'text-primary-600 hover:text-primary-500 dark:text-primary-500 dark:hover:text-primary-400',
'secondary' => 'text-secondary-600 hover:text-secondary-500 dark:text-secondary-500 dark:hover:text-secondary-400',
'success' => 'text-success-600 hover:text-success-500 dark:text-success-500 dark:hover:text-success-400',
'warning' => 'text-warning-600 hover:text-warning-500 dark:text-warning-500 dark:hover:text-warning-400',
default => $color,
default => 'text-custom-600 hover:text-custom-500 dark:text-custom-500 dark:hover:text-custom-400',
},
match ($size) {
'sm' => 'text-sm',
'md' => 'text-sm',
'lg' => 'text-base',
},
];
]);
$linkStyles = \Illuminate\Support\Arr::toCssStyles([
\Filament\Support\get_color_css_variables($color, shades: [400, 500, 600]) => $color !== 'gray',
]);
$iconSize = match ($iconSize) {
'sm' => 'h-4 w-4',
@@ -51,19 +49,9 @@
'ms-1' => $iconPosition === 'after',
]);
$indicatorClasses = \Illuminate\Support\Arr::toCssClasses([
'filament-link-indicator absolute -top-1 -end-1 inline-flex items-center justify-center h-4 w-4 rounded-full text-[0.5rem] font-medium text-white',
match ($indicatorColor) {
'danger' => 'bg-danger-600',
'gray' => 'bg-gray-600',
'info' => 'bg-info-600',
'primary' => 'bg-primary-600',
'secondary' => 'bg-secondary-600',
'success' => 'bg-success-600',
'warning' => 'bg-warning-600',
default => $indicatorColor,
},
]);
$indicatorClasses = 'filament-link-indicator absolute -end-1 -top-1 inline-flex h-4 w-4 items-center justify-center rounded-full bg-custom-600 text-[0.5rem] font-medium text-white';
$indicatorStyles = \Filament\Support\get_color_css_variables($color, shades: [600]);
$wireTarget = $attributes->whereStartsWith(['wire:target', 'wire:click'])->first();
@@ -85,7 +73,11 @@
@if ($tooltip)
x-tooltip.raw="{{ $tooltip }}"
@endif
{{ $attributes->class($linkClasses) }}
{{
$attributes
->class([$linkClasses])
->style([$linkStyles])
}}
>
@if ($icon && $iconPosition === 'before')
<x-filament::icon
@@ -108,7 +100,10 @@
@endif
@if ($indicator)
<span class="{{ $indicatorClasses }}">
<span
class="{{ $indicatorClasses }}"
style="{{ $indicatorStyles }}"
>
{{ $indicator }}
</span>
@endif
@@ -130,7 +125,8 @@
'disabled' => $disabled,
'type' => $type,
], escape: false)
->class($linkClasses)
->class([$linkClasses])
->style([$linkStyles])
}}
>
@if ($iconPosition === 'before')
@@ -178,7 +174,10 @@
@endif
@if ($indicator)
<span class="{{ $indicatorClasses }}">
<span
class="{{ $indicatorClasses }}"
style="{{ $indicatorStyles }}"
>
{{ $indicator }}
</span>
@endif
@@ -7,7 +7,7 @@
'description' => null,
'heading',
'icon' => null,
'iconColor' => null,
'iconColor' => 'gray',
'iconSize' => 'md',
])
@@ -66,16 +66,7 @@
<x-filament::icon
:name="$icon"
alias="support::section.icon"
:color="match ($iconColor) {
'danger' => 'text-danger-400',
'gray', null => 'text-gray-400',
'info' => 'text-info-400',
'primary' => 'text-primary-400',
'secondary' => 'text-secondary-400',
'success' => 'text-success-400',
'warning' => 'text-warning-400',
default => $iconColor,
}"
color="text-custom-400"
:size="match ($iconSize) {
'sm' => 'h-4 w-4',
'md' => 'h-5 w-5',
@@ -83,6 +74,7 @@
default => $iconSize,
}"
class="filament-section-component-header-icon"
:style="\Filament\Support\get_color_css_variables($iconColor, shades: [400])"
/>
@endif
@@ -3,23 +3,20 @@
'alpineActive' => null,
'badge' => null,
'icon' => null,
'iconColor' => null,
'iconColor' => 'gray',
'iconPosition' => 'before',
'tag' => 'button',
'type' => 'button',
])
@php
$iconColorClasses = $active ? null : match ($iconColor) {
'danger' => 'text-danger-600 dark:text-danger-400',
'gray' => 'text-gray-600 dark:text-gray-400',
'info' => 'text-info-600 dark:text-info-400',
'primary' => 'text-primary-600 dark:text-primary-400',
'secondary' => 'text-secondary-600 dark:text-secondary-400',
'success' => 'text-success-600 dark:text-success-400',
'warning' => 'text-warning-600 dark:text-warning-400',
default => $iconColor,
};
$iconColorClasses = \Illuminate\Support\Arr::toCssClasses([
'text-custom-600 dark:text-custom-400' => $active,
]);
$iconStyles = \Illuminate\Support\Arr::toCssStyles([
\Filament\Support\get_color_css_variables($iconColor, shades: [400, 600]) => $iconColorClasses,
]);
@endphp
<{{ $tag }}
@@ -51,6 +48,7 @@
:color="$iconColorClasses"
alias="support::tabs.item"
size="h-5 w-5"
:style="$iconStyles"
x-bind:class="{
'{{ $iconColorClasses }}': ! ({{ $alpineActive }}),
}"
@@ -67,6 +65,7 @@
:color="$iconColorClasses"
alias="support::tabs.item"
size="h-5 w-5"
:style="$iconStyles"
x-bind:class="{
'{{ $iconColorClasses }}': ! ({{ $alpineActive }}),
}"
@@ -3,6 +3,7 @@
namespace Filament\Support\Assets;
use Exception;
use Filament\Support\Facades\FilamentColor;
use Illuminate\Support\Arr;
class AssetManager
@@ -198,8 +199,17 @@ class AssetManager
*/
public function renderStyles(?array $packages = null): string
{
$variables = [];
foreach (FilamentColor::getColors() as $name => $shades) {
foreach ($shades as $shade => $color) {
$variables["{$name}-{$shade}"] = $color;
}
}
return view('filament::assets', [
'assets' => $this->getStyles($packages),
'cssVariables' => $variables,
])->render();
}
@@ -1,6 +1,6 @@
<?php
namespace Filament\Support;
namespace Filament\Support\Colors;
use Spatie\Color\Hex;
use Spatie\Color\Rgb;
@@ -0,0 +1,57 @@
<?php
namespace Filament\Support\Colors;
class ColorManager
{
/**
* @var array<string, array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string}>
*/
protected array $colors = [];
/**
* @param array<string, array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | string> $colors
*/
public function register(array $colors): static
{
foreach ($colors as $name => $color) {
$this->colors[$name] = $this->processColor($color);
}
return $this;
}
/**
* @param array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | string $color
* @return array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | string
*/
public function processColor(array | string $color): array | string
{
if (is_string($color) && str_starts_with($color, '#')) {
return Color::hex($color);
}
if (is_string($color) && str_starts_with($color, 'rgb')) {
return Color::rgb($color);
}
return $color;
}
/**
* @return array<string, array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string}>
*/
public function getColors(): array
{
return [
'danger' => Color::Red,
'gray' => Color::Gray,
'info' => Color::Blue,
'primary' => Color::Amber,
'secondary' => Color::Gray,
'success' => Color::Green,
'warning' => Color::Amber,
...$this->colors,
];
}
}
@@ -0,0 +1,31 @@
<?php
namespace Filament\Support\Concerns;
use Closure;
trait HasColor
{
/**
* @var string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | Closure | null
*/
protected string | array | Closure | null $color = null;
/**
* @param string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | Closure | null $color
*/
public function color(string | array | Closure | null $color): static
{
$this->color = $color;
return $this;
}
/**
* @return string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null
*/
public function getColor(): string | array | null
{
return $this->evaluate($this->color);
}
}
+26 -3
View File
@@ -8,7 +8,12 @@ trait HasIcon
{
protected string | Closure | null $icon = null;
protected string | Closure | null $iconColor = null;
/**
* @var string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | Closure | null
*/
protected string | array | Closure | null $iconColor = null;
protected string | Closure | null $iconPosition = null;
protected string | Closure | null $iconSize = null;
@@ -19,13 +24,23 @@ trait HasIcon
return $this;
}
public function iconColor(string | Closure | null $color): static
/**
* @param string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | Closure | null $color
*/
public function iconColor(string | array | Closure | null $color): static
{
$this->iconColor = $color;
return $this;
}
public function iconPosition(string | Closure | null $position): static
{
$this->iconPosition = $position;
return $this;
}
public function iconSize(string | Closure | null $size): static
{
$this->iconSize = $size;
@@ -38,11 +53,19 @@ trait HasIcon
return $this->evaluate($this->icon);
}
public function getIconColor(): ?string
/**
* @return string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null
*/
public function getIconColor(): string | array | null
{
return $this->evaluate($this->iconColor);
}
public function getIconPosition(): ?string
{
return $this->evaluate($this->iconPosition) ?? 'before';
}
public function getIconSize(): ?string
{
return $this->evaluate($this->iconSize);
+4 -1
View File
@@ -4,5 +4,8 @@ namespace Filament\Support\Contracts;
interface HasColor
{
public function getColor(): ?string;
/**
* @return string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null
*/
public function getColor(): string | array | null;
}
@@ -0,0 +1,20 @@
<?php
namespace Filament\Support\Facades;
use Filament\Support\Colors\ColorManager;
use Illuminate\Support\Facades\Facade;
/**
* @method static void register(array $colors)
* @method static array<string, array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string}> getColors()
*
* @see ColorManager
*/
class FilamentColor extends Facade
{
protected static function getFacadeAccessor(): string
{
return ColorManager::class;
}
}
@@ -5,6 +5,7 @@ namespace Filament\Support;
use Composer\InstalledVersions;
use Filament\Support\Assets\AssetManager;
use Filament\Support\Assets\Js;
use Filament\Support\Colors\ColorManager;
use Filament\Support\Commands\AssetsCommand;
use Filament\Support\Commands\CheckTranslationsCommand;
use Filament\Support\Commands\InstallCommand;
@@ -41,23 +42,22 @@ class SupportServiceProvider extends PackageServiceProvider
{
$this->app->scoped(
AssetManager::class,
function () {
return new AssetManager();
},
fn () => new AssetManager(),
);
$this->app->scoped(
ColorManager::class,
fn () => new ColorManager(),
);
$this->app->scoped(
IconManager::class,
function () {
return new IconManager();
},
fn () => new IconManager(),
);
$this->app->scoped(
SanitizerInterface::class,
function () {
return Sanitizer::create(require __DIR__ . '/../config/html-sanitizer.php');
},
fn () => Sanitizer::create(require __DIR__ . '/../config/html-sanitizer.php'),
);
}
+25
View File
@@ -45,6 +45,31 @@ if (! function_exists('Filament\Support\locale_has_pluralization')) {
}
}
if (! function_exists('Filament\Support\get_color_css_variables')) {
/**
* @param string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} $color
* @param array<int> $shades
*/
function get_color_css_variables(string | array $color, array $shades): string
{
$variables = [];
if (is_string($color)) {
foreach ($shades as $shade) {
$variables[] = "--c-{$shade}:var(--{$color}-{$shade})";
}
}
if (is_array($color)) {
foreach ($shades as $shade) {
$variables[] = "--c-{$shade}:{$color[$shade]}";
}
}
return implode(';', $variables);
}
}
if (! function_exists('Filament\Support\prepare_inherited_attributes')) {
function prepare_inherited_attributes(ComponentAttributeBag $attributes): ComponentAttributeBag
{
@@ -8,7 +8,7 @@ use Filament\Http\Middleware\DispatchServingFilamentEvent;
use Filament\Pages;
use Filament\Panel;
use Filament\PanelProvider;
use Filament\Support\Color;
use Filament\Support\Colors\Color;
use Filament\Widgets;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use Illuminate\Cookie\Middleware\EncryptCookies;
@@ -27,7 +27,9 @@ class AdminPanelProvider extends PanelProvider
->id('admin')
->path('admin')
->login()
->primaryColor(Color::Amber)
->colors([
'primary' => Color::Amber,
])
->discoverResources(in: app_path('Filament/Resources'), for: 'App\\Filament\\Resources')
->discoverPages(in: app_path('Filament/Pages'), for: 'App\\Filament\\Pages')
->pages([
+4 -4
View File
@@ -73,9 +73,9 @@ namespace Livewire\Features\SupportUnitTesting\Tests {
public function assertTableActionDoesNotHaveLabel(string $name, string $label): static {}
public function assertTableActionHasColor(string $name, string $color): static {}
public function assertTableActionHasColor(string $name, string | array $color): static {}
public function assertTableActionDoesNotHaveColor(string $name, string $color): static {}
public function assertTableActionDoesNotHaveColor(string $name, string | array $color): static {}
public function assertTableBulkActionHasIcon(string $name, string $icon): static {}
@@ -85,9 +85,9 @@ namespace Livewire\Features\SupportUnitTesting\Tests {
public function assertTableBulkActionDoesNotHaveLabel(string $name, string $label): static {}
public function assertTableBulkActionHasColor(string $name, string $color): static {}
public function assertTableBulkActionHasColor(string $name, string | array $color): static {}
public function assertTableBulkActionDoesNotHaveColor(string $name, string $color): static {}
public function assertTableBulkActionDoesNotHaveColor(string $name, string | array $color): static {}
public function assertTableActionHasUrl(string $name, string $url): static {}
@@ -14,16 +14,7 @@
<x-filament::icon
:name="$icon"
alias="tables::columns.icon"
:color="match ($color = $getColor($state)) {
'danger' => 'text-danger-500',
'gray', null => 'text-gray-500',
'info' => 'text-info-500',
'primary' => 'text-primary-500',
'secondary' => 'text-secondary-500',
'success' => 'text-success-500',
'warning' => 'text-warning-500',
default => $color,
}"
color="text-custom-500"
:size="match ($size = ($getSize($state) ?? 'lg')) {
'xs' => 'h-3 w-3 filament-tables-icon-column-icon-size-xs',
'sm' => 'h-4 w-4 filament-tables-icon-column-icon-size-sm',
@@ -32,6 +23,7 @@
'xl' => 'h-7 w-7 filament-tables-icon-column-icon-size-xl',
default => $size,
}"
:style="\Filament\Support\get_color_css_variables($getColor($state) ?? 'gray', shades: [500])"
/>
@endif
@endforeach
@@ -20,17 +20,9 @@
<x-filament::icon
:name="$icon"
alias="tables::columns.summaries.icon-count"
:color="match ($color) {
'danger' => 'text-danger-500',
'gray', null => 'text-gray-500',
'info' => 'text-info-500',
'primary' => 'text-primary-500',
'secondary' => 'text-secondary-500',
'success' => 'text-success-500',
'warning' => 'text-warning-500',
default => $color,
}"
color="text-custom-500"
size="h-4 w-4"
:style="\Filament\Support\get_color_css_variables(json_decode($color) ?? 'gray', shades: [500])"
/>
</div>
@endif
@@ -57,6 +57,7 @@
@foreach ($arrayState as $state)
@php
$formattedState = $formatState($state);
$color = $getColor($state) ?? 'gray';
$icon = $getIcon($state);
@endphp
@@ -67,26 +68,15 @@
'inline-flex items-center space-x-1 rtl:space-x-reverse',
'filament-tables-text-column-badge min-h-6 justify-center whitespace-nowrap rounded-xl px-2 py-0.5' => $isBadge,
'whitespace-normal' => $canWrap,
($isBadge ? match ($color = $getColor($state)) {
'danger' => 'filament-tables-text-column-badge-color-danger bg-danger-500/10 text-danger-700 dark:text-danger-500',
'gray', null => 'filament-tables-text-column-badge-color-gray bg-gray-500/10 text-gray-700 dark:bg-gray-500/20 dark:text-gray-300',
'info' => 'filament-tables-text-column-badge-color-info bg-info-500/10 text-info-700 dark:text-info-500',
'primary' => 'filament-tables-text-column-badge-color-primary bg-primary-500/10 text-primary-700 dark:text-primary-500',
'secondary' => 'filament-tables-text-column-badge-color-secondary bg-secondary-500/10 text-secondary-700 dark:text-secondary-500',
'success' => 'filament-tables-text-column-badge-color-success bg-success-500/10 text-success-700 dark:text-success-500',
'warning' => 'filament-tables-text-column-badge-color-warning bg-warning-500/10 text-warning-700 dark:text-warning-500',
default => $color,
} : null),
((! ($isBadge || $isClickable)) ? match ($color = $getColor($state)) {
'danger' => 'text-danger-600',
'gray' => 'text-gray-600 dark:text-gray-400',
'info' => 'text-info-600',
'primary' => 'text-primary-600',
'secondary' => 'text-secondary-600',
'success' => 'text-success-600',
'warning' => 'text-warning-600',
default => $color,
} : null),
"filament-tables-text-column-badge-color-{$color}" => $isBadge && is_string($color),
match ($color) {
'gray' => 'bg-gray-500/10 text-gray-700 dark:bg-gray-500/20 dark:text-gray-300',
default => 'bg-custom-500/10 text-custom-700 dark:text-custom-500',
} => $isBadge,
match ($color) {
'gray' => null,
default => 'text-custom-600 dark:text-custom-400',
} => ! ($isBadge || $isClickable),
match ($size = ($isBadge ? 'xs' : $getSize($state))) {
'xs' => 'text-xs',
'sm', null => 'text-sm',
@@ -112,6 +102,16 @@
default => null,
},
])
@style([
\Filament\Support\get_color_css_variables(
$color,
shades: match (true) {
$isBadge => [500, 700],
! ($isBadge || $isClickable) => [400, 600],
default => [],
},
) => $color !== 'gray',
])
>
@if ($icon && $iconPosition === 'before')
<x-filament::icon
@@ -19,8 +19,8 @@
}}
>
@php
$offColor = $getOffColor();
$onColor = $getOnColor();
$offColor = $getOffColor() ?? 'gray';
$onColor = $getOnColor() ?? 'primary';
@endphp
<button
@@ -46,32 +46,28 @@
"
x-tooltip="error"
x-bind:class="
(state ? '{{
match ($getOnColor()) {
'danger' => 'bg-danger-600',
'gray' => 'bg-gray-600',
'info' => 'bg-info-600',
'primary', null => 'bg-primary-600',
'secondary' => 'bg-secondary-600',
'success' => 'bg-success-600',
'warning' => 'bg-warning-600',
default => $onColor,
}
}}' : '{{
match ($getOffColor()) {
'danger' => 'bg-danger-600',
'gray' => 'bg-gray-600',
'info' => 'bg-info-600',
'primary' => 'bg-primary-600',
'secondary' => 'bg-secondary-600',
'success' => 'bg-success-600',
'warning' => 'bg-warning-600',
null => 'bg-gray-200 dark:bg-gray-700',
default => $offColor,
}
}}') +
(
state
? '{{
match ($onColor) {
'gray' => 'bg-gray-200 dark:bg-gray-700',
default => 'bg-custom-600',
}
}}'
: '{{
match ($offColor) {
'gray' => 'bg-gray-200 dark:bg-gray-700',
default => 'bg-custom-600',
}
}}'
) +
(isLoading ? ' opacity-70 pointer-events-none' : '')
"
x-bind:style="
state
? '{{ \Filament\Support\get_color_css_variables($onColor, shades: [600]) }}'
: '{{ \Filament\Support\get_color_css_variables($offColor, shades: [600]) }}'
"
@disabled($isDisabled())
type="button"
class="relative ms-4 inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent outline-none transition-colors duration-200 ease-in-out disabled:pointer-events-none disabled:opacity-70"
@@ -87,16 +83,9 @@
<x-filament::icon
:name="$getOffIcon()"
alias="tables::columns.toggle.off"
:color="match ($offColor) {
'danger' => 'text-danger-600',
'gray' => 'text-gray-600',
'info' => 'text-info-600',
'primary' => 'text-primary-600',
'secondary' => 'text-secondary-600',
'success' => 'text-success-600',
'warning' => 'text-warning-600',
null => 'text-gray-400 dark:text-gray-700',
default => $offColor,
:color="match ($onColor) {
'gray' => 'text-gray-400 dark:text-gray-700',
default => 'text-custom-600',
}"
size="h-3 w-3"
/>
@@ -116,14 +105,8 @@
:name="$getOnIcon()"
alias="tables::columns.toggle.on"
:color="match ($onColor) {
'danger' => 'text-danger-600',
'gray' => 'text-gray-600',
'info' => 'text-info-600',
'primary', null => 'text-primary-600',
'secondary' => 'text-secondary-600',
'success' => 'text-success-600',
'warning' => 'text-warning-600',
default => $onColor,
'gray' => 'text-gray-400 dark:text-gray-700',
default => 'text-custom-600',
}"
size="h-3 w-3"
x-cloak="x-cloak"
@@ -8,9 +8,15 @@ use Filament\Tables\Columns\Column;
trait HasColor
{
protected string | bool | Closure | null $color = null;
/**
* @var string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | bool | Closure | null
*/
protected string | array | bool | Closure | null $color = null;
public function color(string | bool | Closure | null $color): static
/**
* @param string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | bool | Closure | null $color
*/
public function color(string | array | bool | Closure | null $color): static
{
$this->color = $color;
@@ -43,7 +49,10 @@ trait HasColor
return $this;
}
public function getColor(mixed $state): ?string
/**
* @return string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null
*/
public function getColor(mixed $state): string | array | null
{
$color = $this->evaluate($this->color, [
'state' => $state,
+36 -9
View File
@@ -22,11 +22,17 @@ class IconColumn extends Column
protected bool | Closure $isBoolean = false;
protected string | Closure | null $falseColor = null;
/**
* @var string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | Closure | null
*/
protected string | array | Closure | null $falseColor = null;
protected string | Closure | null $falseIcon = null;
protected string | Closure | null $trueColor = null;
/**
* @var string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | Closure | null
*/
protected string | array | Closure | null $trueColor = null;
protected string | Closure | null $trueIcon = null;
@@ -46,7 +52,10 @@ class IconColumn extends Column
return $this;
}
public function false(string | Closure | null $icon = null, string | Closure | null $color = null): static
/**
* @param string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | Closure | null $color
*/
public function false(string | Closure | null $icon = null, string | array | Closure | null $color = null): static
{
$this->falseIcon($icon);
$this->falseColor($color);
@@ -54,7 +63,10 @@ class IconColumn extends Column
return $this;
}
public function falseColor(string | Closure | null $color): static
/**
* @param string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | Closure | null $color
*/
public function falseColor(string | array | Closure | null $color): static
{
$this->boolean();
$this->falseColor = $color;
@@ -70,7 +82,10 @@ class IconColumn extends Column
return $this;
}
public function true(string | Closure | null $icon = null, string | Closure | null $color = null): static
/**
* @param string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | Closure | null $color
*/
public function true(string | Closure | null $icon = null, string | array | Closure | null $color = null): static
{
$this->trueIcon($icon);
$this->trueColor($color);
@@ -78,7 +93,10 @@ class IconColumn extends Column
return $this;
}
public function trueColor(string | Closure | null $color): static
/**
* @param string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | Closure | null $color
*/
public function trueColor(string | array | Closure | null $color): static
{
$this->boolean();
$this->trueColor = $color;
@@ -123,7 +141,10 @@ class IconColumn extends Column
return $state ? $this->getTrueIcon() : $this->getFalseIcon();
}
public function getColor(mixed $state): ?string
/**
* @return string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null
*/
public function getColor(mixed $state): string | array | null
{
if (filled($color = $this->getBaseColor($state))) {
return $color;
@@ -140,7 +161,10 @@ class IconColumn extends Column
return $state ? $this->getTrueColor() : $this->getFalseColor();
}
public function getFalseColor(): string
/**
* @return string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string}
*/
public function getFalseColor(): string | array
{
return $this->evaluate($this->falseColor) ?? 'danger';
}
@@ -150,7 +174,10 @@ class IconColumn extends Column
return $this->evaluate($this->falseIcon) ?? 'heroicon-o-x-circle';
}
public function getTrueColor(): string
/**
* @return string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string}
*/
public function getTrueColor(): string | array
{
return $this->evaluate($this->trueColor) ?? 'success';
}
@@ -40,7 +40,7 @@ class Count extends Summarizer
foreach ($query->clone()->pluck($attribute) as $value) {
$column->record($this->getQuery()->getModel()->setAttribute($attribute, $value));
$state = $column->getState();
$color = $column->getColor($state);
$color = json_encode($column->getColor($state));
$icon = $column->getIcon($state);
$state[$color] ??= [];
@@ -14,7 +14,7 @@ trait CanSpanColumns
/**
* @var array<string, int | string | Closure | null> | int | string | Closure | null
*/
protected array | int | string | Closure | null $columnStart = 1;
protected array | int | string | Closure | null $columnStart = null;
/**
* @param array<string, int | string | Closure | null> | int | string | Closure | null $span
+10 -6
View File
@@ -441,7 +441,7 @@ class TestsActions
public function assertTableActionHasColor(): Closure
{
return function (string | array $name, string $color, $record = null): static {
return function (string | array $name, string | array $color, $record = null): static {
$name = $this->parseNestedActionName($name);
/** @phpstan-ignore-next-line */
@@ -457,11 +457,13 @@ class TestsActions
$livewireClass = $this->instance()::class;
$prettyName = implode(' > ', $name);
$colorName = is_string($color) ? $color : 'custom';
Assert::assertTrue(
$action->getColor() === $color,
message: filled($record) ?
"Failed asserting that a table action with name [{$prettyName}] has color [{$color}] on the [{$livewireClass}] component for record [{$record}]." :
"Failed asserting that a table action with name [{$prettyName}] has color [{$color}] on the [{$livewireClass}] component.",
"Failed asserting that a table action with name [{$prettyName}] has [{$colorName}] color on the [{$livewireClass}] component for record [{$record}]." :
"Failed asserting that a table action with name [{$prettyName}] has [{$colorName}] color on the [{$livewireClass}] component.",
);
return $this;
@@ -470,7 +472,7 @@ class TestsActions
public function assertTableActionDoesNotHaveColor(): Closure
{
return function (string | array $name, string $color, $record = null): static {
return function (string | array $name, string | array $color, $record = null): static {
$name = $this->parseNestedActionName($name);
/** @phpstan-ignore-next-line */
@@ -486,11 +488,13 @@ class TestsActions
$livewireClass = $this->instance()::class;
$prettyName = implode(' > ', $name);
$colorName = is_string($color) ? $color : 'custom';
Assert::assertFalse(
$action->getColor() === $color,
message: filled($record) ?
"Failed asserting that a table action with name [{$prettyName}] does not have color [{$color}] on the [{$livewireClass}] component for record [{$record}]." :
"Failed asserting that a table action with name [{$prettyName}] does not have color [{$color}] on the [{$livewireClass}] component.",
"Failed asserting that a table action with name [{$prettyName}] does not have [{$colorName}] color on the [{$livewireClass}] component for record [{$record}]." :
"Failed asserting that a table action with name [{$prettyName}] does not have [{$colorName}] color on the [{$livewireClass}] component.",
);
return $this;
@@ -346,7 +346,7 @@ class TestsBulkActions
public function assertTableBulkActionHasColor(): Closure
{
return function (string $name, string $color, $record = null): static {
return function (string $name, string | array $color, $record = null): static {
$name = $this->parseActionName($name);
/** @phpstan-ignore-next-line */
@@ -356,9 +356,11 @@ class TestsBulkActions
$livewireClass = $this->instance()::class;
$colorName = is_string($color) ? $color : 'custom';
Assert::assertTrue(
$action->getColor() === $color,
"Failed asserting that a table bulk action with name [{$name}] has color [{$color}] on the [{$livewireClass}] component for record [{$record}]."
"Failed asserting that a table bulk action with name [{$name}] has [{$colorName}] color on the [{$livewireClass}] component for record [{$record}]."
);
return $this;
@@ -367,7 +369,7 @@ class TestsBulkActions
public function assertTableBulkActionDoesNotHaveColor(): Closure
{
return function (string $name, string $color, $record = null): static {
return function (string $name, string | array $color, $record = null): static {
$name = $this->parseActionName($name);
/** @phpstan-ignore-next-line */
@@ -377,9 +379,11 @@ class TestsBulkActions
$livewireClass = $this->instance()::class;
$colorName = is_string($color) ? $color : 'custom';
Assert::assertFalse(
$action->getColor() === $color,
"Failed asserting that a table bulk action with name [{$name}] does not have color [{$color}] on the [{$livewireClass}] component for record [{$record}]."
"Failed asserting that a table bulk action with name [{$name}] does not have [{$colorName}] color on the [{$livewireClass}] component for record [{$record}]."
);
return $this;
@@ -58,7 +58,7 @@ use Filament\Navigation\NavigationGroup;
use Filament\Pages;
use Filament\Panel;
use Filament\PanelProvider;
use Filament\Support\Color;
use Filament\Support\Colors\Color;
use Filament\Widgets;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use Illuminate\Cookie\Middleware\EncryptCookies;
@@ -77,7 +77,9 @@ class {$className} extends PanelProvider
->id('{$id}')
->path({$pathPhp}){$domainPhp}
->login(){$authGuardPhp}
->primaryColor(Color::Amber)
->colors([
'primary' => Color::Amber,
])
->discoverResources(in: {$resourcesPathPhp}, for: {$resourcesNamespacePhp})
->discoverPages(in: {$pagesPathPhp}, for: {$pagesNamespacePhp})
->pages([
@@ -36,19 +36,8 @@
@if ($description = $getDescription())
<div
@class([
'flex items-center space-x-1 text-sm font-medium rtl:space-x-reverse',
match ($descriptionColor = $getDescriptionColor()) {
'danger' => 'text-danger-600',
'gray', null => 'text-gray-600',
'info' => 'text-info-600',
'primary' => 'text-primary-600',
'secondary' => 'text-secondary-600',
'success' => 'text-success-600',
'warning' => 'text-warning-600',
default => $descriptionColor,
},
])
class="flex items-center space-x-1 text-sm font-medium text-custom-600 rtl:space-x-reverse"
style="{{ \Filament\Support\get_color_css_variables($getDescriptionColor(), shades: [600]) }}"
>
@if ($descriptionIcon && ($descriptionIconPosition === 'before'))
<x-filament::icon
@@ -86,44 +75,16 @@
initChart()
"
class="absolute inset-x-0 bottom-0 overflow-hidden rounded-b-xl"
style="{{ \Filament\Support\get_color_css_variables($getChartColor() ?? 'gray', shades: [50, 400, 700]) }}"
>
<canvas x-ref="canvas" class="h-6"></canvas>
@php
$chartColor = $getChartColor();
@endphp
<span
x-ref="backgroundColorElement"
@class([
match ($chartColor) {
'danger' => 'text-danger-50 dark:text-danger-700',
'gray', null => 'text-gray-50 dark:text-gray-700',
'info' => 'text-info-50 dark:text-info-700',
'primary' => 'text-primary-50 dark:text-primary-700',
'secondary' => 'text-secondary-50 dark:text-secondary-700',
'success' => 'text-success-50 dark:text-success-700',
'warning' => 'text-warning-50 dark:text-warning-700',
default => $chartColor,
},
])
class="text-custom-50 dark:text-custom-700"
></span>
<span
x-ref="borderColorElement"
@class([
match ($chartColor) {
'danger' => 'text-danger-400',
'gray', null => 'text-gray-400',
'info' => 'text-info-400',
'primary' => 'text-primary-400',
'secondary' => 'text-secondary-400',
'success' => 'text-success-400',
'warning' => 'text-warning-400',
default => $chartColor,
},
])
></span>
<span x-ref="borderColorElement" class="text-custom-400"></span>
</div>
@endif
</{!! $tag !!}>
@@ -16,9 +16,15 @@ class Card extends Component implements Htmlable
*/
protected ?array $chart = null;
protected ?string $chartColor = null;
/**
* @var string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null
*/
protected string | array | null $chartColor = null;
protected ?string $color = null;
/**
* @var string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null
*/
protected string | array | null $color = null;
protected ?string $icon = null;
@@ -28,7 +34,10 @@ class Card extends Component implements Htmlable
protected ?string $descriptionIconPosition = null;
protected ?string $descriptionColor = null;
/**
* @var string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null
*/
protected string | array | null $descriptionColor = null;
/**
* @var array<string, scalar>
@@ -65,14 +74,20 @@ class Card extends Component implements Htmlable
return app(static::class, ['label' => $label, 'value' => $value]);
}
public function chartColor(?string $color): static
/**
* @param string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null $color
*/
public function chartColor(string | array | null $color): static
{
$this->chartColor = $color;
return $this;
}
public function color(?string $color): static
/**
* @param string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null $color
*/
public function color(string | array | null $color): static
{
$this->color = $color;
@@ -93,7 +108,10 @@ class Card extends Component implements Htmlable
return $this;
}
public function descriptionColor(?string $color): static
/**
* @param string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null $color
*/
public function descriptionColor(string | array | null $color): static
{
$this->descriptionColor = $color;
@@ -175,12 +193,18 @@ class Card extends Component implements Htmlable
return $this->chart;
}
public function getChartColor(): ?string
/**
* @return string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null
*/
public function getChartColor(): string | array | null
{
return $this->chartColor ?? $this->color;
}
public function getColor(): ?string
/**
* @return string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null
*/
public function getColor(): string | array | null
{
return $this->color;
}
@@ -195,7 +219,10 @@ class Card extends Component implements Htmlable
return $this->description;
}
public function getDescriptionColor(): ?string
/**
* @return string | array{50: string, 100: string, 200: string, 300: string, 400: string, 500: string, 600: string, 700: string, 800: string, 900: string, 950: string} | null
*/
public function getDescriptionColor(): string | array | null
{
return $this->descriptionColor ?? $this->color;
}