Merge branch '4.x' into Feature-Reorderable-columns

This commit is contained in:
Kenneth Sese
2025-06-12 00:02:56 -06:00
66 changed files with 1064 additions and 287 deletions
Generated
+140 -152
View File
@@ -129,16 +129,16 @@
},
{
"name": "aws/aws-sdk-php",
"version": "3.343.21",
"version": "3.344.4",
"source": {
"type": "git",
"url": "https://github.com/aws/aws-sdk-php.git",
"reference": "4bee288751c58598625ea2e8f30258404dd98757"
"reference": "df314cc4169146d87a15bb408edfaf94ab9ca08c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/4bee288751c58598625ea2e8f30258404dd98757",
"reference": "4bee288751c58598625ea2e8f30258404dd98757",
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/df314cc4169146d87a15bb408edfaf94ab9ca08c",
"reference": "df314cc4169146d87a15bb408edfaf94ab9ca08c",
"shasum": ""
},
"require": {
@@ -220,9 +220,9 @@
"support": {
"forum": "https://github.com/aws/aws-sdk-php/discussions",
"issues": "https://github.com/aws/aws-sdk-php/issues",
"source": "https://github.com/aws/aws-sdk-php/tree/3.343.21"
"source": "https://github.com/aws/aws-sdk-php/tree/3.344.4"
},
"time": "2025-05-29T18:11:11+00:00"
"time": "2025-06-10T18:04:31+00:00"
},
{
"name": "blade-ui-kit/blade-heroicons",
@@ -469,16 +469,16 @@
},
{
"name": "brick/math",
"version": "0.12.3",
"version": "0.13.1",
"source": {
"type": "git",
"url": "https://github.com/brick/math.git",
"reference": "866551da34e9a618e64a819ee1e01c20d8a588ba"
"reference": "fc7ed316430118cc7836bf45faff18d5dfc8de04"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/brick/math/zipball/866551da34e9a618e64a819ee1e01c20d8a588ba",
"reference": "866551da34e9a618e64a819ee1e01c20d8a588ba",
"url": "https://api.github.com/repos/brick/math/zipball/fc7ed316430118cc7836bf45faff18d5dfc8de04",
"reference": "fc7ed316430118cc7836bf45faff18d5dfc8de04",
"shasum": ""
},
"require": {
@@ -517,7 +517,7 @@
],
"support": {
"issues": "https://github.com/brick/math/issues",
"source": "https://github.com/brick/math/tree/0.12.3"
"source": "https://github.com/brick/math/tree/0.13.1"
},
"funding": [
{
@@ -525,7 +525,7 @@
"type": "github"
}
],
"time": "2025-02-28T13:11:00+00:00"
"time": "2025-03-29T13:50:30+00:00"
},
{
"name": "carbonphp/carbon-doctrine-types",
@@ -1492,16 +1492,16 @@
},
{
"name": "filp/whoops",
"version": "2.18.0",
"version": "2.18.1",
"source": {
"type": "git",
"url": "https://github.com/filp/whoops.git",
"reference": "a7de6c3c6c3c022f5cfc337f8ede6a14460cf77e"
"reference": "8fcc6a862f2e7b94eb4221fd0819ddba3d30ab26"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/filp/whoops/zipball/a7de6c3c6c3c022f5cfc337f8ede6a14460cf77e",
"reference": "a7de6c3c6c3c022f5cfc337f8ede6a14460cf77e",
"url": "https://api.github.com/repos/filp/whoops/zipball/8fcc6a862f2e7b94eb4221fd0819ddba3d30ab26",
"reference": "8fcc6a862f2e7b94eb4221fd0819ddba3d30ab26",
"shasum": ""
},
"require": {
@@ -1551,7 +1551,7 @@
],
"support": {
"issues": "https://github.com/filp/whoops/issues",
"source": "https://github.com/filp/whoops/tree/2.18.0"
"source": "https://github.com/filp/whoops/tree/2.18.1"
},
"funding": [
{
@@ -1559,7 +1559,7 @@
"type": "github"
}
],
"time": "2025-03-15T12:00:00+00:00"
"time": "2025-06-03T18:56:14+00:00"
},
{
"name": "fruitcake/php-cors",
@@ -2322,16 +2322,16 @@
},
{
"name": "larastan/larastan",
"version": "v3.4.0",
"version": "v3.4.2",
"source": {
"type": "git",
"url": "https://github.com/larastan/larastan.git",
"reference": "1042fa0c2ee490bb6da7381f3323f7292ad68222"
"reference": "36706736a0c51d3337478fab9c919d78d2e03404"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/larastan/larastan/zipball/1042fa0c2ee490bb6da7381f3323f7292ad68222",
"reference": "1042fa0c2ee490bb6da7381f3323f7292ad68222",
"url": "https://api.github.com/repos/larastan/larastan/zipball/36706736a0c51d3337478fab9c919d78d2e03404",
"reference": "36706736a0c51d3337478fab9c919d78d2e03404",
"shasum": ""
},
"require": {
@@ -2399,7 +2399,7 @@
],
"support": {
"issues": "https://github.com/larastan/larastan/issues",
"source": "https://github.com/larastan/larastan/tree/v3.4.0"
"source": "https://github.com/larastan/larastan/tree/v3.4.2"
},
"funding": [
{
@@ -2407,24 +2407,24 @@
"type": "github"
}
],
"time": "2025-04-22T09:44:59+00:00"
"time": "2025-06-10T09:34:58+00:00"
},
{
"name": "laravel/framework",
"version": "v12.16.0",
"version": "v12.18.0",
"source": {
"type": "git",
"url": "https://github.com/laravel/framework.git",
"reference": "293bb1c70224faebfd3d4328e201c37115da055f"
"reference": "7d264a0dad2bfc5c154240b38e8ce9b2c4cdd14d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/framework/zipball/293bb1c70224faebfd3d4328e201c37115da055f",
"reference": "293bb1c70224faebfd3d4328e201c37115da055f",
"url": "https://api.github.com/repos/laravel/framework/zipball/7d264a0dad2bfc5c154240b38e8ce9b2c4cdd14d",
"reference": "7d264a0dad2bfc5c154240b38e8ce9b2c4cdd14d",
"shasum": ""
},
"require": {
"brick/math": "^0.11|^0.12",
"brick/math": "^0.11|^0.12|^0.13",
"composer-runtime-api": "^2.2",
"doctrine/inflector": "^2.0.5",
"dragonmantank/cron-expression": "^3.4",
@@ -2622,20 +2622,20 @@
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
},
"time": "2025-05-27T15:49:44+00:00"
"time": "2025-06-10T14:48:34+00:00"
},
{
"name": "laravel/pail",
"version": "v1.2.2",
"version": "v1.2.3",
"source": {
"type": "git",
"url": "https://github.com/laravel/pail.git",
"reference": "f31f4980f52be17c4667f3eafe034e6826787db2"
"reference": "8cc3d575c1f0e57eeb923f366a37528c50d2385a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/pail/zipball/f31f4980f52be17c4667f3eafe034e6826787db2",
"reference": "f31f4980f52be17c4667f3eafe034e6826787db2",
"url": "https://api.github.com/repos/laravel/pail/zipball/8cc3d575c1f0e57eeb923f366a37528c50d2385a",
"reference": "8cc3d575c1f0e57eeb923f366a37528c50d2385a",
"shasum": ""
},
"require": {
@@ -2655,7 +2655,7 @@
"orchestra/testbench-core": "^8.13|^9.0|^10.0",
"pestphp/pest": "^2.20|^3.0",
"pestphp/pest-plugin-type-coverage": "^2.3|^3.0",
"phpstan/phpstan": "^1.10",
"phpstan/phpstan": "^1.12.27",
"symfony/var-dumper": "^6.3|^7.0"
},
"type": "library",
@@ -2691,6 +2691,7 @@
"description": "Easily delve into your Laravel application's log files directly from the command line.",
"homepage": "https://github.com/laravel/pail",
"keywords": [
"dev",
"laravel",
"logs",
"php",
@@ -2700,7 +2701,7 @@
"issues": "https://github.com/laravel/pail/issues",
"source": "https://github.com/laravel/pail"
},
"time": "2025-01-28T15:15:15+00:00"
"time": "2025-06-05T13:55:57+00:00"
},
{
"name": "laravel/pint",
@@ -4505,16 +4506,16 @@
},
{
"name": "nette/utils",
"version": "v4.0.6",
"version": "v4.0.7",
"source": {
"type": "git",
"url": "https://github.com/nette/utils.git",
"reference": "ce708655043c7050eb050df361c5e313cf708309"
"reference": "e67c4061eb40b9c113b218214e42cb5a0dda28f2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nette/utils/zipball/ce708655043c7050eb050df361c5e313cf708309",
"reference": "ce708655043c7050eb050df361c5e313cf708309",
"url": "https://api.github.com/repos/nette/utils/zipball/e67c4061eb40b9c113b218214e42cb5a0dda28f2",
"reference": "e67c4061eb40b9c113b218214e42cb5a0dda28f2",
"shasum": ""
},
"require": {
@@ -4585,22 +4586,22 @@
],
"support": {
"issues": "https://github.com/nette/utils/issues",
"source": "https://github.com/nette/utils/tree/v4.0.6"
"source": "https://github.com/nette/utils/tree/v4.0.7"
},
"time": "2025-03-30T21:06:30+00:00"
"time": "2025-06-03T04:55:08+00:00"
},
{
"name": "nikic/php-parser",
"version": "v5.4.0",
"version": "v5.5.0",
"source": {
"type": "git",
"url": "https://github.com/nikic/PHP-Parser.git",
"reference": "447a020a1f875a434d62f2a401f53b82a396e494"
"reference": "ae59794362fe85e051a58ad36b289443f57be7a9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/447a020a1f875a434d62f2a401f53b82a396e494",
"reference": "447a020a1f875a434d62f2a401f53b82a396e494",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/ae59794362fe85e051a58ad36b289443f57be7a9",
"reference": "ae59794362fe85e051a58ad36b289443f57be7a9",
"shasum": ""
},
"require": {
@@ -4643,29 +4644,29 @@
],
"support": {
"issues": "https://github.com/nikic/PHP-Parser/issues",
"source": "https://github.com/nikic/PHP-Parser/tree/v5.4.0"
"source": "https://github.com/nikic/PHP-Parser/tree/v5.5.0"
},
"time": "2024-12-30T11:07:19+00:00"
"time": "2025-05-31T08:24:38+00:00"
},
{
"name": "nunomaduro/collision",
"version": "v8.8.0",
"version": "v8.8.1",
"source": {
"type": "git",
"url": "https://github.com/nunomaduro/collision.git",
"reference": "4cf9f3b47afff38b139fb79ce54fc71799022ce8"
"reference": "44ccb82e3e21efb5446748d2a3c81a030ac22bd5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nunomaduro/collision/zipball/4cf9f3b47afff38b139fb79ce54fc71799022ce8",
"reference": "4cf9f3b47afff38b139fb79ce54fc71799022ce8",
"url": "https://api.github.com/repos/nunomaduro/collision/zipball/44ccb82e3e21efb5446748d2a3c81a030ac22bd5",
"reference": "44ccb82e3e21efb5446748d2a3c81a030ac22bd5",
"shasum": ""
},
"require": {
"filp/whoops": "^2.18.0",
"nunomaduro/termwind": "^2.3.0",
"filp/whoops": "^2.18.1",
"nunomaduro/termwind": "^2.3.1",
"php": "^8.2.0",
"symfony/console": "^7.2.5"
"symfony/console": "^7.3.0"
},
"conflict": {
"laravel/framework": "<11.44.2 || >=13.0.0",
@@ -4673,15 +4674,15 @@
},
"require-dev": {
"brianium/paratest": "^7.8.3",
"larastan/larastan": "^3.2",
"laravel/framework": "^11.44.2 || ^12.6",
"laravel/pint": "^1.21.2",
"laravel/sail": "^1.41.0",
"laravel/sanctum": "^4.0.8",
"larastan/larastan": "^3.4.2",
"laravel/framework": "^11.44.2 || ^12.18",
"laravel/pint": "^1.22.1",
"laravel/sail": "^1.43.1",
"laravel/sanctum": "^4.1.1",
"laravel/tinker": "^2.10.1",
"orchestra/testbench-core": "^9.12.0 || ^10.1",
"pestphp/pest": "^3.8.0",
"sebastian/environment": "^7.2.0 || ^8.0"
"orchestra/testbench-core": "^9.12.0 || ^10.4",
"pestphp/pest": "^3.8.2",
"sebastian/environment": "^7.2.1 || ^8.0"
},
"type": "library",
"extra": {
@@ -4744,7 +4745,7 @@
"type": "patreon"
}
],
"time": "2025-04-03T14:33:09+00:00"
"time": "2025-06-11T01:04:21+00:00"
},
{
"name": "nunomaduro/termwind",
@@ -5067,16 +5068,16 @@
},
{
"name": "orchestra/sidekick",
"version": "v1.2.10",
"version": "v1.2.12",
"source": {
"type": "git",
"url": "https://github.com/orchestral/sidekick.git",
"reference": "0beebe28b5f67840dad9b7a695f8015c6c2879f7"
"reference": "c182e9f91d7aa68417eae0585e004fbbc7beac26"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/orchestral/sidekick/zipball/0beebe28b5f67840dad9b7a695f8015c6c2879f7",
"reference": "0beebe28b5f67840dad9b7a695f8015c6c2879f7",
"url": "https://api.github.com/repos/orchestral/sidekick/zipball/c182e9f91d7aa68417eae0585e004fbbc7beac26",
"reference": "c182e9f91d7aa68417eae0585e004fbbc7beac26",
"shasum": ""
},
"require": {
@@ -5118,22 +5119,22 @@
"description": "Packages Toolkit Utilities and Helpers for Laravel",
"support": {
"issues": "https://github.com/orchestral/sidekick/issues",
"source": "https://github.com/orchestral/sidekick/tree/v1.2.10"
"source": "https://github.com/orchestral/sidekick/tree/v1.2.12"
},
"time": "2025-05-25T03:49:19+00:00"
"time": "2025-06-08T03:58:04+00:00"
},
{
"name": "orchestra/testbench",
"version": "v10.3.0",
"version": "v10.4.0",
"source": {
"type": "git",
"url": "https://github.com/orchestral/testbench.git",
"reference": "6d0930e33724809a2dbd3c9ecd686295b899e6c9"
"reference": "36674005fb1b5cddfd953b8c440507394af8695d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/orchestral/testbench/zipball/6d0930e33724809a2dbd3c9ecd686295b899e6c9",
"reference": "6d0930e33724809a2dbd3c9ecd686295b899e6c9",
"url": "https://api.github.com/repos/orchestral/testbench/zipball/36674005fb1b5cddfd953b8c440507394af8695d",
"reference": "36674005fb1b5cddfd953b8c440507394af8695d",
"shasum": ""
},
"require": {
@@ -5141,7 +5142,7 @@
"fakerphp/faker": "^1.23",
"laravel/framework": "^12.8.0",
"mockery/mockery": "^1.6.10",
"orchestra/testbench-core": "^10.3.0",
"orchestra/testbench-core": "^10.4.0",
"orchestra/workbench": "^10.0.6",
"php": "^8.2",
"phpunit/phpunit": "^11.5.3|^12.0.1",
@@ -5173,27 +5174,27 @@
],
"support": {
"issues": "https://github.com/orchestral/testbench/issues",
"source": "https://github.com/orchestral/testbench/tree/v10.3.0"
"source": "https://github.com/orchestral/testbench/tree/v10.4.0"
},
"time": "2025-05-12T06:36:03+00:00"
"time": "2025-06-08T23:29:04+00:00"
},
{
"name": "orchestra/testbench-core",
"version": "v10.3.0",
"version": "v10.4.0",
"source": {
"type": "git",
"url": "https://github.com/orchestral/testbench-core.git",
"reference": "3cacf7bc512665b9eb6d2380bb4433574458a557"
"reference": "d1c45a7be15c4d99fb7d48685b038dd39acc7b84"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/orchestral/testbench-core/zipball/3cacf7bc512665b9eb6d2380bb4433574458a557",
"reference": "3cacf7bc512665b9eb6d2380bb4433574458a557",
"url": "https://api.github.com/repos/orchestral/testbench-core/zipball/d1c45a7be15c4d99fb7d48685b038dd39acc7b84",
"reference": "d1c45a7be15c4d99fb7d48685b038dd39acc7b84",
"shasum": ""
},
"require": {
"composer-runtime-api": "^2.2",
"orchestra/sidekick": "^1.1.5|^1.2.0",
"orchestra/sidekick": "~1.1.16|^1.2.12",
"php": "^8.2",
"symfony/deprecation-contracts": "^2.5|^3.0",
"symfony/polyfill-php83": "^1.32"
@@ -5203,7 +5204,7 @@
"laravel/framework": "<12.8.0|>=13.0.0",
"laravel/serializable-closure": "<1.3.0|>=2.0.0 <2.0.3|>=3.0.0",
"nunomaduro/collision": "<8.0.0|>=9.0.0",
"phpunit/phpunit": "<10.5.35|>=11.0.0 <11.5.3|12.0.0|>=12.2.0"
"phpunit/phpunit": "<10.5.35|>=11.0.0 <11.5.3|12.0.0|>=12.3.0"
},
"require-dev": {
"fakerphp/faker": "^1.24",
@@ -5268,7 +5269,7 @@
"issues": "https://github.com/orchestral/testbench/issues",
"source": "https://github.com/orchestral/testbench-core"
},
"time": "2025-05-12T05:41:57+00:00"
"time": "2025-06-08T04:36:36+00:00"
},
{
"name": "orchestra/workbench",
@@ -5923,16 +5924,16 @@
},
{
"name": "phiki/phiki",
"version": "v1.1.5",
"version": "v1.1.6",
"source": {
"type": "git",
"url": "https://github.com/phikiphp/phiki.git",
"reference": "30280485e06201b28532f4e441580c2c969e539e"
"reference": "3174d8cb309bdccc32b7a33500379de76148256b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phikiphp/phiki/zipball/30280485e06201b28532f4e441580c2c969e539e",
"reference": "30280485e06201b28532f4e441580c2c969e539e",
"url": "https://api.github.com/repos/phikiphp/phiki/zipball/3174d8cb309bdccc32b7a33500379de76148256b",
"reference": "3174d8cb309bdccc32b7a33500379de76148256b",
"shasum": ""
},
"require": {
@@ -5971,9 +5972,9 @@
"description": "Syntax highlighting using TextMate grammars in PHP.",
"support": {
"issues": "https://github.com/phikiphp/phiki/issues",
"source": "https://github.com/phikiphp/phiki/tree/v1.1.5"
"source": "https://github.com/phikiphp/phiki/tree/v1.1.6"
},
"time": "2025-04-06T23:40:06+00:00"
"time": "2025-06-06T20:18:29+00:00"
},
{
"name": "php-di/invoker",
@@ -6032,16 +6033,16 @@
},
{
"name": "php-di/php-di",
"version": "7.0.10",
"version": "7.0.11",
"source": {
"type": "git",
"url": "https://github.com/PHP-DI/PHP-DI.git",
"reference": "0d1ed64126577e9a095b3204dcaee58cf76432c2"
"reference": "32f111a6d214564520a57831d397263e8946c1d2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHP-DI/PHP-DI/zipball/0d1ed64126577e9a095b3204dcaee58cf76432c2",
"reference": "0d1ed64126577e9a095b3204dcaee58cf76432c2",
"url": "https://api.github.com/repos/PHP-DI/PHP-DI/zipball/32f111a6d214564520a57831d397263e8946c1d2",
"reference": "32f111a6d214564520a57831d397263e8946c1d2",
"shasum": ""
},
"require": {
@@ -6089,7 +6090,7 @@
],
"support": {
"issues": "https://github.com/PHP-DI/PHP-DI/issues",
"source": "https://github.com/PHP-DI/PHP-DI/tree/7.0.10"
"source": "https://github.com/PHP-DI/PHP-DI/tree/7.0.11"
},
"funding": [
{
@@ -6101,7 +6102,7 @@
"type": "tidelift"
}
],
"time": "2025-04-22T08:53:15+00:00"
"time": "2025-06-03T07:45:57+00:00"
},
{
"name": "phpdocumentor/reflection-common",
@@ -7662,20 +7663,20 @@
},
{
"name": "ramsey/uuid",
"version": "4.7.6",
"version": "4.8.1",
"source": {
"type": "git",
"url": "https://github.com/ramsey/uuid.git",
"reference": "91039bc1faa45ba123c4328958e620d382ec7088"
"reference": "fdf4dd4e2ff1813111bd0ad58d7a1ddbb5b56c28"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ramsey/uuid/zipball/91039bc1faa45ba123c4328958e620d382ec7088",
"reference": "91039bc1faa45ba123c4328958e620d382ec7088",
"url": "https://api.github.com/repos/ramsey/uuid/zipball/fdf4dd4e2ff1813111bd0ad58d7a1ddbb5b56c28",
"reference": "fdf4dd4e2ff1813111bd0ad58d7a1ddbb5b56c28",
"shasum": ""
},
"require": {
"brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11 || ^0.12",
"brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11 || ^0.12 || ^0.13",
"ext-json": "*",
"php": "^8.0",
"ramsey/collection": "^1.2 || ^2.0"
@@ -7684,26 +7685,23 @@
"rhumsaa/uuid": "self.version"
},
"require-dev": {
"captainhook/captainhook": "^5.10",
"captainhook/captainhook": "^5.25",
"captainhook/plugin-composer": "^5.3",
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
"doctrine/annotations": "^1.8",
"ergebnis/composer-normalize": "^2.15",
"mockery/mockery": "^1.3",
"dealerdirect/phpcodesniffer-composer-installer": "^1.0",
"ergebnis/composer-normalize": "^2.47",
"mockery/mockery": "^1.6",
"paragonie/random-lib": "^2",
"php-mock/php-mock": "^2.2",
"php-mock/php-mock-mockery": "^1.3",
"php-parallel-lint/php-parallel-lint": "^1.1",
"phpbench/phpbench": "^1.0",
"phpstan/extension-installer": "^1.1",
"phpstan/phpstan": "^1.8",
"phpstan/phpstan-mockery": "^1.1",
"phpstan/phpstan-phpunit": "^1.1",
"phpunit/phpunit": "^8.5 || ^9",
"ramsey/composer-repl": "^1.4",
"slevomat/coding-standard": "^8.4",
"squizlabs/php_codesniffer": "^3.5",
"vimeo/psalm": "^4.9"
"php-mock/php-mock": "^2.6",
"php-mock/php-mock-mockery": "^1.5",
"php-parallel-lint/php-parallel-lint": "^1.4.0",
"phpbench/phpbench": "^1.2.14",
"phpstan/extension-installer": "^1.4",
"phpstan/phpstan": "^2.1",
"phpstan/phpstan-mockery": "^2.0",
"phpstan/phpstan-phpunit": "^2.0",
"phpunit/phpunit": "^9.6",
"slevomat/coding-standard": "^8.18",
"squizlabs/php_codesniffer": "^3.13"
},
"suggest": {
"ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.",
@@ -7738,32 +7736,22 @@
],
"support": {
"issues": "https://github.com/ramsey/uuid/issues",
"source": "https://github.com/ramsey/uuid/tree/4.7.6"
"source": "https://github.com/ramsey/uuid/tree/4.8.1"
},
"funding": [
{
"url": "https://github.com/ramsey",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/ramsey/uuid",
"type": "tidelift"
}
],
"time": "2024-04-27T21:32:50+00:00"
"time": "2025-06-01T06:28:46+00:00"
},
{
"name": "rector/rector",
"version": "2.0.17",
"version": "2.0.18",
"source": {
"type": "git",
"url": "https://github.com/rectorphp/rector.git",
"reference": "caa4ffda1d48bde44434e6ba95d132ec32e7fd40"
"reference": "be3a452085b524a04056e3dfe72d861948711062"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/rectorphp/rector/zipball/caa4ffda1d48bde44434e6ba95d132ec32e7fd40",
"reference": "caa4ffda1d48bde44434e6ba95d132ec32e7fd40",
"url": "https://api.github.com/repos/rectorphp/rector/zipball/be3a452085b524a04056e3dfe72d861948711062",
"reference": "be3a452085b524a04056e3dfe72d861948711062",
"shasum": ""
},
"require": {
@@ -7801,7 +7789,7 @@
],
"support": {
"issues": "https://github.com/rectorphp/rector/issues",
"source": "https://github.com/rectorphp/rector/tree/2.0.17"
"source": "https://github.com/rectorphp/rector/tree/2.0.18"
},
"funding": [
{
@@ -7809,7 +7797,7 @@
"type": "github"
}
],
"time": "2025-05-30T10:59:08+00:00"
"time": "2025-06-11T11:19:37+00:00"
},
{
"name": "ryangjchandler/blade-capture-directive",
@@ -8970,16 +8958,16 @@
},
{
"name": "spatie/eloquent-sortable",
"version": "4.4.2",
"version": "4.5.0",
"source": {
"type": "git",
"url": "https://github.com/spatie/eloquent-sortable.git",
"reference": "69e0e258e19513cf261305dd17717ee731aaede3"
"reference": "76c8fbc79e1d5eec85e7145e46c7f0a65e1f4cda"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/spatie/eloquent-sortable/zipball/69e0e258e19513cf261305dd17717ee731aaede3",
"reference": "69e0e258e19513cf261305dd17717ee731aaede3",
"url": "https://api.github.com/repos/spatie/eloquent-sortable/zipball/76c8fbc79e1d5eec85e7145e46c7f0a65e1f4cda",
"reference": "76c8fbc79e1d5eec85e7145e46c7f0a65e1f4cda",
"shasum": ""
},
"require": {
@@ -9028,7 +9016,7 @@
],
"support": {
"issues": "https://github.com/spatie/eloquent-sortable/issues",
"source": "https://github.com/spatie/eloquent-sortable/tree/4.4.2"
"source": "https://github.com/spatie/eloquent-sortable/tree/4.5.0"
},
"funding": [
{
@@ -9040,20 +9028,20 @@
"type": "github"
}
],
"time": "2025-02-19T07:17:00+00:00"
"time": "2025-06-03T12:41:10+00:00"
},
{
"name": "spatie/image",
"version": "3.8.3",
"version": "3.8.4",
"source": {
"type": "git",
"url": "https://github.com/spatie/image.git",
"reference": "54a7331a4d1ba7712603dd058522613506d2dfe0"
"reference": "df315a480113081c5c27958bee9bf3f97f36fe76"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/spatie/image/zipball/54a7331a4d1ba7712603dd058522613506d2dfe0",
"reference": "54a7331a4d1ba7712603dd058522613506d2dfe0",
"url": "https://api.github.com/repos/spatie/image/zipball/df315a480113081c5c27958bee9bf3f97f36fe76",
"reference": "df315a480113081c5c27958bee9bf3f97f36fe76",
"shasum": ""
},
"require": {
@@ -9101,7 +9089,7 @@
"spatie"
],
"support": {
"source": "https://github.com/spatie/image/tree/3.8.3"
"source": "https://github.com/spatie/image/tree/3.8.4"
},
"funding": [
{
@@ -9113,7 +9101,7 @@
"type": "github"
}
],
"time": "2025-04-25T08:04:51+00:00"
"time": "2025-06-04T08:18:18+00:00"
},
{
"name": "spatie/image-optimizer",
@@ -13442,7 +13430,7 @@
],
"aliases": [],
"minimum-stability": "dev",
"stability-flags": {},
"stability-flags": [],
"prefer-stable": true,
"prefer-lowest": false,
"platform": {
@@ -13450,6 +13438,6 @@
"composer-runtime-api": "^2.1",
"ext-intl": "*"
},
"platform-dev": {},
"plugin-api-version": "2.6.0"
"platform-dev": [],
"plugin-api-version": "2.3.0"
}
+62 -9
View File
@@ -38,14 +38,38 @@ Installation comes in two flavors, depending on whether you want to build an app
## Installing the panel builder
Since Filament v4 is in beta, you will need to set the `minimum-stability` in your `composer.json` file to be `beta` before installing any packages. Either adjust it manually or via CLI:
```bash
composer config minimum-stability beta
```
Your `composer.json` should look like this:
```json
{
"minimum-stability": "beta"
}
```
Install the Filament Panel Builder by running the following commands in your Laravel project directory:
```bash
composer require filament/filament
composer require filament/filament:"^4.0"
php artisan filament:install --panels
```
<Aside variant="warning">
When using Windows PowerShell to install Filament, you may need to run the command below, since it ignores `^` characters in version constraints:
```bash
composer require '"filament/filament:^4.0"'
php artisan filament:install --panels
```
</Aside>
This will create and register a new [Laravel service provider](https://laravel.com/docs/providers) called `app/Providers/Filament/AdminPanelProvider.php`.
<Aside variant="tip">
@@ -70,21 +94,50 @@ Open `/admin` in your web browser, sign in, and [start building your app](../get
## Installing the individual components
First, install the Filament components you want to use with Composer:
Since Filament v4 is in beta, you will need to set the `minimum-stability` in your `composer.json` file to be `beta` before installing any packages. Either adjust it manually or via CLI:
```bash
composer config minimum-stability beta
```
Your `composer.json` should look like this:
```json
{
"minimum-stability": "beta"
}
```
Install the Filament components you want to use with Composer:
```bash
composer require
filament/tables
filament/schemas
filament/forms
filament/infolists
filament/actions
filament/notifications
filament/widgets
filament/tables:"^4.0"
filament/schemas:"^4.0"
filament/forms:"^4.0"
filament/infolists:"^4.0"
filament/actions:"^4.0"
filament/notifications:"^4.0"
filament/widgets:"^4.0"
```
You can install additional packages later in your project without having to repeat these installation steps.
<Aside variant="warning">
When using Windows PowerShell to install Filament, you may need to run the command below, since it ignores `^` characters in version constraints:
```bash
composer require
'"filament/tables:^4.0"'
'"filament/schemas:^4.0"'
'"filament/forms:^4.0"'
'"filament/infolists:^4.0"'
'"filament/actions:^4.0"'
'"filament/notifications:^4.0"'
'"filament/widgets:^4.0"'
```
</Aside>
If you only want to use the set of [Blade UI components](../components), you'll need to require `filament/support` at this stage.
<RadioGroup model="laravelProject">
+1 -1
View File
@@ -42,4 +42,4 @@ Custom pages are a blank canvas for you to build whatever you want in a panel. T
Each custom page has a PHP class and a Blade view. The PHP class is technically a [full-page Livewire component](https://livewire.laravel.com/docs/components) (in fact, every page class in a Filament panel is a Livewire component). As such, every page has access to the full power of Livewire to build an interactive server-rendered UI.
To start your journey by creating a custom page, visit the [Custom pages documentation](advanced/custom-pages).
To start your journey by creating a custom page, visit the [Custom pages documentation](navigation/custom-pages).
+6 -2
View File
@@ -400,7 +400,9 @@ public static function getNavigationSort(): ?int
You may group navigation items by specifying a `$navigationGroup` property:
```php
protected static ?string $navigationGroup = 'Shop';
use UnitEnum;
protected static string | UnitEnum | null $navigationGroup = 'Shop';
```
Alternatively, you may use the `getNavigationGroup()` method to set a dynamic group label:
@@ -417,9 +419,11 @@ public static function getNavigationGroup(): ?string
You may group navigation items as children of other items, by passing the label of the parent item as the `$navigationParentItem`:
```php
use UnitEnum;
protected static ?string $navigationParentItem = 'Products';
protected static ?string $navigationGroup = 'Shop';
protected static string | UnitEnum | null $navigationGroup = 'Shop';
```
As seen above, if the parent item has a navigation group, that navigation group must also be defined, so the correct parent item can be identified.
+2 -2
View File
@@ -56,12 +56,12 @@ public static function table(Table $table): Table
Or the `infolist()`:
```php
use App\Filament\Resources\Customers\Schemas\CustomerInfoList;
use App\Filament\Resources\Customers\Schemas\CustomerInfolist;
use Filament\Schemas\Schema;
public static function infolist(Schema $schema): Schema
{
return CustomerInfoList::configure($schema);
return CustomerInfolist::configure($schema);
}
```
+6 -2
View File
@@ -109,7 +109,9 @@ public static function getNavigationBadgeTooltip(): ?string
You may group navigation items by specifying a `$navigationGroup` property on a [resource](resources) and [custom page](custom-pages):
```php
protected static ?string $navigationGroup = 'Settings';
use UnitEnum;
protected static string | UnitEnum | null $navigationGroup = 'Settings';
```
<AutoScreenshot name="panels/navigation/group" alt="Grouped navigation items" version="3.x" />
@@ -121,9 +123,11 @@ All items in the same navigation group will be displayed together under the same
You may group navigation items as children of other items, by passing the label of the parent item as the `$navigationParentItem`:
```php
use UnitEnum;
protected static ?string $navigationParentItem = 'Notifications';
protected static ?string $navigationGroup = 'Settings';
protected static string | UnitEnum | null $navigationGroup = 'Settings';
```
You may also use the `getNavigationParentItem()` method to set a dynamic parent item label:
+1 -1
View File
@@ -75,7 +75,7 @@ You can also conditionally hide a user menu item by using the `visible()` or `hi
```php
use App\Models\Payment;
use Filament\Actions\Action
use Filament\Actions\Action;
Action::make('payments')
->visible(fn (): bool => auth()->user()->can('viewAny', Payment::class))
+2 -2
View File
@@ -95,7 +95,7 @@ By default, the size of the section icon is "large". You can change it to be "sm
## Adding content to the end of the header
You may render additional content at the end of the header, next to the heading and description, using the `headerEnd` slot:
You may render additional content at the end of the header, next to the heading and description, using the `afterHeader` slot:
```blade
<x-filament::section>
@@ -103,7 +103,7 @@ You may render additional content at the end of the header, next to the heading
User details
</x-slot>
<x-slot name="headerEnd">
<x-slot name="afterHeader">
{{-- Input to select the user's ID --}}
</x-slot>
+30 -37
View File
@@ -23,7 +23,21 @@ import Disclosure from "@components/Disclosure.astro"
The upgrade script is not a replacement for the upgrade guide. It handles many small changes that are not mentioned in the upgrade guide, but it does not handle all breaking changes. You should still read the [manual upgrade steps](#breaking-changes-that-must-be-handled-manually) to see what changes you need to make to your code.
</Aside>
The first set to upgrade your Filament app is to run the automated upgrade script. This script will automatically upgrade your application to the latest version of Filament and make changes to your code, which handles most breaking changes:
The first step to upgrade your Filament app is to run the automated upgrade script. Since Filament v4 is in beta, you will need to set the `minimum-stability` in your `composer.json` file to be `beta` before installing any packages. Either adjust it manually or via CLI:
```bash
composer config minimum-stability beta
```
Your `composer.json` should look like this:
```json
{
"minimum-stability": "beta"
}
```
This script will automatically upgrade your application to the latest version of Filament and make changes to your code, which handles most breaking changes:
```bash
composer require filament/upgrade:"^4.0" -W --dev
@@ -31,6 +45,16 @@ composer require filament/upgrade:"^4.0" -W --dev
vendor/bin/filament-v4
```
<Aside variant="warning">
When using Windows PowerShell to install Filament, you may need to run the command below, since it ignores `^` characters in version constraints:
```bash
composer require '"filament/upgrade:^4.0"' -W --dev
vendor/bin/filament-v4
```
</Aside>
<Aside variant="warning">
If installing the upgrade script fails, make sure that your PHPStan version is at least v2, or your Larastan version is at least v3. The script uses Rector v2, which requires PHPStan v2 or higher.
</Aside>
@@ -43,37 +67,6 @@ You can now `composer remove filament/upgrade` as you don't need it anymore.
Some plugins you're using may not be available in v4 just yet. You could temporarily remove them from your `composer.json` file until they've been upgraded, replace them with a similar plugins that are v4-compatible, wait for the plugins to be upgraded before upgrading your app, or even write PRs to help the authors upgrade them.
</Aside>
### Cleaning up your code style after upgrading to v4
The automated upgrade script uses [Rector](https://getrector.org) to make changes to your code. Sometimes, the tool may change how your code is formatted or introduce references to classes that are not yet imported.
Filament suggests using [Laravel Pint](https://laravel.com/docs/12.x/pint) or [PHP CS Fixer](https://cs.symfony.com) to clean up your code style after running the upgrade script.
Specifically, the [`fully_qualified_strict_types` rule](https://cs.symfony.com/doc/rules/import/fully_qualified_strict_types.html) and [`global_namespace_import` rule](https://cs.symfony.com/doc/rules/import/global_namespace_import.html) in these tools will fix any references to classes that are not yet imported, which is a common issue after running the upgrade script.
This is the Laravel Pint configuration that Filament uses for its own codebase if you would like a good starting point:
```json
{
"preset": "laravel",
"rules": {
"blank_line_before_statement": true,
"concat_space": {
"spacing": "one"
},
"fully_qualified_strict_types": {
"import_symbols": true
},
"global_namespace_import": true,
"method_argument_space": true,
"single_trait_insert_per_statement": true,
"types_spaces": {
"space": "single"
}
}
}
```
## Publishing the configuration file
Some changes in Filament v4 can be reverted using the configuration file. If you haven't published the configuration file yet, you can do so by running the following command:
@@ -230,7 +223,7 @@ In v4, the default disk for Filament is set to `local`, and the visibility of fi
Previously, custom theme CSS files contained this:
```cs
```css
@import '../../../../vendor/filament/filament/resources/css/theme.css';
@config 'tailwind.config.js';
@@ -309,9 +302,9 @@ Section::make()
You can preserve the old default behavior across your entire app by adding the following code in the `boot()` method of a service provider like `AppServiceProvider`:
```php
use Filament\Forms\Components\Fieldset;
use Filament\Forms\Components\Grid;
use Filament\Forms\Components\Section;
use Filament\Schemas\Components\Fieldset;
use Filament\Schemas\Components\Grid;
use Filament\Schemas\Components\Section;
Fieldset::configureUsing(fn (Fieldset $fieldset) => $fieldset
->columnSpanFull());
@@ -332,7 +325,7 @@ In v3, the `unique()` method did not ignore the current form's Eloquent record w
In v4, the `unique()` method's `ignoreRecord` parameter defaults to `true`.
If you were previously using `unqiue()` validation rule without the `ignoreRecord` or `ignorable` parameters, you should use `ignoreRecord: false` to disable the new behavior.
If you were previously using `unique()` validation rule without the `ignoreRecord` or `ignorable` parameters, you should use `ignoreRecord: false` to disable the new behavior.
<Aside variant="tip">
You can preserve the old default behavior across your entire app by adding the following code in the `boot()` method of a service provider like `AppServiceProvider`:
@@ -54,6 +54,18 @@ return [
'title' => 'Borrados',
],
'deleted_partial' => [
'title' => 'Borrados :count de :total',
'missing_authorization_failure_message' => 'Usted no tiene permiso para eliminar :count.',
'missing_processing_failure_message' => ':count no se pudieron eliminar.',
],
'deleted_none' => [
'title' => 'No se pudo eliminar',
'missing_authorization_failure_message' => 'Usted no tiene permiso para eliminar :count.',
'missing_processing_failure_message' => ':count no se pudieron eliminar.',
],
],
],
@@ -54,6 +54,18 @@ return [
'title' => 'Registros eliminados',
],
'deleted_partial' => [
'title' => 'Borrados :count de :total',
'missing_authorization_failure_message' => 'Usted no tiene permiso para eliminar :count.',
'missing_processing_failure_message' => ':count no se pudieron eliminar.',
],
'deleted_none' => [
'title' => 'No se pudo eliminar',
'missing_authorization_failure_message' => 'Usted no tiene permiso para eliminar :count.',
'missing_processing_failure_message' => ':count no se pudieron eliminar.',
],
],
],
@@ -0,0 +1,10 @@
<?php
return [
'throttled' => [
'title' => 'Demasiados intentos',
'body' => 'Por favor intente nuevamente en :seconds segundos.',
],
];
@@ -54,6 +54,18 @@ return [
'title' => 'Registros restaurados',
],
'restored_partial' => [
'title' => 'Restaurados :count de :total',
'missing_authorization_failure_message' => 'Usted no tiene permiso para restaurar :count.',
'missing_processing_failure_message' => ':count no se pudieron restaurar.',
],
'restored_none' => [
'title' => 'Failed to restore',
'missing_authorization_failure_message' => 'Usted no tiene permiso para restaurar :count.',
'missing_processing_failure_message' => ':count no se pudieron restaurar.',
],
],
],
@@ -71,7 +71,7 @@ trait HasDropdown
{
$width = $this->evaluate($this->dropdownWidth);
if (! ($width instanceof Width)) {
if (is_string($width)) {
$width = Width::tryFrom($width) ?? $width;
}
+1 -12
View File
@@ -2,9 +2,7 @@
namespace Filament\Actions\Exports\Models;
use App\Models\User;
use Carbon\CarbonInterface;
use Exception;
use Filament\Actions\Exports\Exporter;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Filesystem\Filesystem;
@@ -46,17 +44,8 @@ class Export extends Model
$authenticatable = app(Authenticatable::class);
if ($authenticatable) {
/** @phpstan-ignore-next-line */
return $this->belongsTo($authenticatable::class);
}
if (! class_exists(User::class)) {
throw new Exception('No [App\\Models\\User] model found. Please bind an authenticatable model to the [Illuminate\\Contracts\\Auth\\Authenticatable] interface in a service provider\'s [register()] method.');
}
/** @phpstan-ignore-next-line */
return $this->belongsTo(User::class);
return $this->belongsTo($authenticatable::class);
}
/**
+1 -12
View File
@@ -2,9 +2,7 @@
namespace Filament\Actions\Imports\Models;
use App\Models\User;
use Carbon\CarbonInterface;
use Exception;
use Filament\Actions\Imports\Importer;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Collection;
@@ -52,17 +50,8 @@ class Import extends Model
$authenticatable = app(Authenticatable::class);
if ($authenticatable) {
/** @phpstan-ignore-next-line */
return $this->belongsTo($authenticatable::class);
}
if (! class_exists(User::class)) {
throw new Exception('No [App\\Models\\User] model found. Please bind an authenticatable model to the [Illuminate\\Contracts\\Auth\\Authenticatable] interface in a service provider\'s [register()] method.');
}
/** @phpstan-ignore-next-line */
return $this->belongsTo(User::class);
return $this->belongsTo($authenticatable::class);
}
/**
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -98,7 +98,7 @@ export default function fileUploadFormComponent({
editor: {},
init: async function () {
async init() {
FilePond.setOptions(locales[locale] ?? locales['en'])
this.pond = FilePond.create(this.$refs.input, {
@@ -363,7 +363,7 @@ export default function fileUploadFormComponent({
)
},
getUploadedFiles: async function () {
async getUploadedFiles() {
const uploadedFiles = await getUploadedFilesUsing()
this.fileKeyIndex = uploadedFiles ?? {}
@@ -377,7 +377,7 @@ export default function fileUploadFormComponent({
}, {})
},
getFiles: async function () {
async getFiles() {
await this.getUploadedFiles()
let files = []
@@ -101,7 +101,7 @@ export default function markdownEditorFormComponent({
state,
init: async function () {
async init() {
if (this.$root._editor) {
this.$root._editor.toTextArea()
this.$root._editor = null
@@ -35,7 +35,7 @@ export default function richEditorFormComponent({
editorUpdatedAt: Date.now(),
init: async function () {
async init() {
editor = new Editor({
editable: !isDisabled,
element: this.$refs.editor,
@@ -39,7 +39,7 @@ export default function selectFormComponent({
state,
init: async function () {
async init() {
this.select = new Choices(this.$refs.input, {
allowHTML: isHtmlAllowed,
duplicateItemsAllowed: false,
@@ -165,7 +165,7 @@ export default function selectFormComponent({
this.select = null
},
refreshChoices: async function (config = {}) {
async refreshChoices(config = {}) {
const choices = await this.getChoices(config)
if (!this.select) {
@@ -198,7 +198,7 @@ export default function selectFormComponent({
this.select.setChoices(choices, 'value', 'label', true)
},
getChoices: async function (config = {}) {
async getChoices(config = {}) {
const existingOptions = await this.getExistingOptions(config)
this.isEmpty = existingOptions.length === 0
@@ -208,7 +208,7 @@ export default function selectFormComponent({
)
},
getExistingOptions: async function ({ search, withInitialOptions }) {
async getExistingOptions({ search, withInitialOptions }) {
if (withInitialOptions) {
return options
}
@@ -267,7 +267,7 @@ export default function selectFormComponent({
return state?.toString()
},
getMissingOptions: async function (existingOptions) {
async getMissingOptions(existingOptions) {
let state = this.formatState(this.state)
if ([null, undefined, '', [], {}].includes(state)) {
@@ -302,6 +302,28 @@ return [
],
'modal_table_select' => [
'actions' => [
'select' => [
'label' => 'Seleccionar',
'actions' => [
'select' => [
'label' => 'Seleccionar',
],
],
],
],
],
'radio' => [
'boolean' => [
@@ -65,7 +65,7 @@
>
<input
x-on:focus="$refs.panel.open($refs.input)"
x-on:keydown.enter.stop.prevent="togglePanelVisibility()"
x-on:keydown.enter.prevent.stop="togglePanelVisibility()"
x-ref="input"
{{
$getExtraInputAttributeBag()
@@ -111,18 +111,18 @@
<button
x-ref="button"
x-on:click="togglePanelVisibility()"
x-on:keydown.enter.stop.prevent="
x-on:keydown.enter.prevent.stop="
if (! $el.disabled) {
isOpen() ? selectDate() : togglePanelVisibility()
}
"
x-on:keydown.arrow-left.stop.prevent="if (! $el.disabled) focusPreviousDay()"
x-on:keydown.arrow-right.stop.prevent="if (! $el.disabled) focusNextDay()"
x-on:keydown.arrow-up.stop.prevent="if (! $el.disabled) focusPreviousWeek()"
x-on:keydown.arrow-down.stop.prevent="if (! $el.disabled) focusNextWeek()"
x-on:keydown.backspace.stop.prevent="if (! $el.disabled) clearState()"
x-on:keydown.clear.stop.prevent="if (! $el.disabled) clearState()"
x-on:keydown.delete.stop.prevent="if (! $el.disabled) clearState()"
x-on:keydown.arrow-left.prevent.stop="if (! $el.disabled) focusPreviousDay()"
x-on:keydown.arrow-right.prevent.stop="if (! $el.disabled) focusNextDay()"
x-on:keydown.arrow-up.prevent.stop="if (! $el.disabled) focusPreviousWeek()"
x-on:keydown.arrow-down.prevent.stop="if (! $el.disabled) focusNextWeek()"
x-on:keydown.backspace.prevent.stop="if (! $el.disabled) clearState()"
x-on:keydown.clear.prevent.stop="if (! $el.disabled) clearState()"
x-on:keydown.delete.prevent.stop="if (! $el.disabled) clearState()"
aria-label="{{ $placeholder }}"
type="button"
tabindex="-1"
@@ -227,7 +227,7 @@
</x-slot>
<input
x-on:keyup.enter.stop.prevent="{!! $input['alpineSaveHandler'] !!}"
x-on:keyup.enter.prevent.stop="{!! $input['alpineSaveHandler'] !!}"
x-on:blur="{!! $input['alpineSaveHandler'] !!}"
x-ref="{{ $input['ref'] }}"
x-on:keydown.enter.prevent
@@ -252,7 +252,7 @@
<button
aria-label="{{ $action['label'] }}"
type="button"
x-on:click.stop.prevent="{{ $action['alpineClickHandler'] }}"
x-on:click.prevent.stop="{{ $action['alpineClickHandler'] }}"
x-tooltip="{ content: @js($action['label']), theme: $store.theme }"
class="fi-btn"
>
@@ -278,7 +278,7 @@
@foreach ($ratiosChunk as $label => $ratio)
<button
type="button"
x-on:click.stop.prevent="
x-on:click.prevent.stop="
currentRatio = @js($label) {!! ';' !!}
editor.setAspectRatio(@js($ratio))
"
@@ -308,7 +308,7 @@
<button
type="button"
x-on:click.stop.prevent="editor.reset()"
x-on:click.prevent.stop="editor.reset()"
{{
(new \Illuminate\View\ComponentAttributeBag)
->color(\Filament\Support\View\Components\ButtonComponent::class, 'danger')
@@ -10,11 +10,13 @@ use Filament\Schemas\Components\Concerns\HasLabel;
use Filament\Schemas\Components\Concerns\HasName;
use Filament\Schemas\Components\Utilities\Get;
use Filament\Schemas\Components\Utilities\Set;
use Filament\Support\Concerns\CanBeContained;
use Illuminate\Contracts\Support\Htmlable;
use Illuminate\Database\Eloquent\Relations\MorphTo;
class MorphToSelect extends Component
{
use CanBeContained;
use Concerns\CanAllowHtml;
use Concerns\CanBeMarkedAsRequired;
use Concerns\CanBeNative;
+2 -2
View File
File diff suppressed because one or more lines are too long
@@ -0,0 +1,19 @@
<?php
return [
'notifications' => [
'blocked' => [
'title' => 'Cambio de correo electrónico bloqueado',
'body' => 'Ha bloqueado con éxito un intento de cambio de correo electrónico a :email. Si no hizo la solicitud original, contáctenos de inmediato.',
],
'failed' => [
'title' => 'Error al bloquear el cambio de correo electrónico',
'body' => 'Lamentablemente, no se pudo evitar que el correo electrónico cambiara a :email, ya que estaba verificado antes de que se bloqueara. Si no hizo la solicitud original, póngase en contacto con nosotros de inmediato.',
],
],
];
@@ -0,0 +1,14 @@
<?php
return [
'notifications' => [
'verified' => [
'title' => 'Dirección de correo electrónico cambiada',
'body' => 'Su dirección de correo electrónico ha sido cambiada con éxito a :email.',
],
],
];
@@ -0,0 +1,71 @@
<?php
return [
'label' => 'Apagar',
'modal' => [
'heading' => 'Deshabilitar la aplicación de autenticación',
'description' => '¿Seguro que quiere dejar de usar la aplicación de autenticación? Deshabilitarla eliminará una capa adicional de seguridad de su cuenta.',
'form' => [
'code' => [
'label' => 'Ingrese el código de 6 dígitos de la aplicación de autenticación',
'validation_attribute' => 'código',
'actions' => [
'use_recovery_code' => [
'label' => 'Use un código de recuperación en su lugar',
],
],
'messages' => [
'invalid' => 'El código ingresado no es válido.',
],
],
'recovery_code' => [
'label' => 'O bien, ingrese un código de recuperación',
'validation_attribute' => 'código de recuperación',
'messages' => [
'invalid' => 'El código de recuperación ingresado no es válido.',
],
],
],
'actions' => [
'submit' => [
'label' => 'Deshabilitar aplicación de autenticación',
],
],
],
'notifications' => [
'disabled' => [
'title' => 'La aplicación de autenticación ha sido deshabilitada',
],
],
];
@@ -0,0 +1,77 @@
<?php
return [
'label' => 'Regenerar códigos de recuperación',
'modal' => [
'heading' => 'Regenerar códigos de recuperación de la aplicación de autenticación',
'description' => 'Si pierde sus códigos de recuperación, puede regenerarlos aquí. Sus códigos de recuperación antiguos se invalidarán inmediatamente.',
'form' => [
'code' => [
'label' => 'Ingrese el código de 6 dígitos de la aplicación de autenticación',
'validation_attribute' => 'código',
'messages' => [
'invalid' => 'El código ingresado no es válido.',
],
],
'password' => [
'label' => 'O bien, introduzca su contraseña actual',
'validation_attribute' => 'contraseña',
],
],
'actions' => [
'submit' => [
'label' => 'Regenerar códigos de recuperación',
],
],
],
'notifications' => [
'regenerated' => [
'title' => 'Se han generado nuevos códigos de recuperación de la aplicación de autenticación',
],
],
'show_new_recovery_codes' => [
'modal' => [
'heading' => 'Nuevos códigos de recuperación',
'description' => 'Guarde los siguientes códigos de recuperación en un lugar seguro. Solo se mostrarán una vez, y los necesitará si pierde el acceso a su aplicación de autenticación:',
'actions' => [
'submit' => [
'label' => 'Cerrar',
],
],
],
],
];
@@ -0,0 +1,81 @@
<?php
return [
'label' => 'Configurar',
'modal' => [
'heading' => 'Configurar la aplicación de autenticación',
'description' => <<<'BLADE'
Usted necesitará una aplicación como Google Authenticator (<x-filament::link href="https://itunes.apple.com/us/app/google-authenticator/id388497605" target="_blank">iOS</x-filament::link>, <x-filament::link href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2" target="_blank">Android</x-filament::link>) para completar este proceso.
BLADE,
'content' => [
'qr_code' => [
'instruction' => 'Escanée este código QR con su aplicación de autenticación:',
'alt' => 'Código QR para escanear con una aplicación de autenticación',
],
'text_code' => [
'instruction' => 'O ingrese este código manualmente:',
'messages' => [
'copied' => 'Copiado',
],
],
'recovery_codes' => [
'instruction' => 'Guarde los siguientes códigos de recuperación en un lugar seguro. Solo se mostrarán una vez, y los necesitará si pierde el acceso a su aplicación de autenticación:',
],
],
'form' => [
'code' => [
'label' => 'Ingrese el código de 6 dígitos de la aplicación de autenticación',
'validation_attribute' => 'código',
'below_content' => 'Necesitará ingresar el código de 6 dígitos de su aplicación de autenticación cada vez que inicie sesión o realice acciones sensibles.',
'messages' => [
'invalid' => 'El código ingresado no es válido.',
],
],
],
'actions' => [
'submit' => [
'label' => 'Habilitar aplicación de autenticación',
],
],
],
'notifications' => [
'enabled' => [
'title' => 'La aplicación de autenticación ha sido habilitada',
],
],
];
@@ -0,0 +1,64 @@
<?php
return [
'management_schema' => [
'actions' => [
'label' => 'Aplicación de autenticación',
'below_content' => 'Utilice una aplicación segura para generar un código temporal para verificar el inicio de sesión.',
'messages' => [
'enabled' => 'Habilitada',
'disabled' => 'Deshabilitada',
],
],
],
'login_form' => [
'label' => 'Use un código de su aplicación de autenticación',
'code' => [
'label' => 'Ingrese el código de 6 dígitos de la aplicación de autenticación',
'validation_attribute' => 'código',
'actions' => [
'use_recovery_code' => [
'label' => 'Use un código de recuperación en su lugar',
],
],
'messages' => [
'invalid' => 'El código ingresado no es válido.',
],
],
'recovery_code' => [
'label' => 'O bien, ingrese un código de recuperación',
'validation_attribute' => 'código de recuperación',
'messages' => [
'invalid' => 'El código de recuperación ingresado no es válido.',
],
],
],
];
@@ -0,0 +1,67 @@
<?php
return [
'label' => 'Apagar',
'modal' => [
'heading' => 'Deshabilitar códigos de verificación por correo',
'description' => '¿Seguro que desea dejar de recibir códigos de verificación por correo? Desactivar esta opción eliminará una capa adicional de seguridad de su cuenta.',
'form' => [
'code' => [
'label' => 'Ingrese el código de 6 dígitos que te enviamos por correo electrónico',
'validation_attribute' => 'código',
'actions' => [
'resend' => [
'label' => 'Enviar un código nuevo por correo electrónico',
'notifications' => [
'resent' => [
'title' => 'Le hemos enviado un código nuevo por correo electrónico.',
],
],
],
],
'messages' => [
'invalid' => 'El código ingresado no es válido.',
],
],
],
'actions' => [
'submit' => [
'label' => 'Deshabilitar códigos de verificación por correo',
],
],
],
'notifications' => [
'disabled' => [
'title' => 'Los códigos de verificación por correo han sido deshabilitados',
],
],
];
@@ -0,0 +1,67 @@
<?php
return [
'label' => 'Configurar',
'modal' => [
'heading' => 'Configurar códigos de verificación por correo electrónico',
'description' => 'Usted necesitará ingresar el código de 6 dígitos que le enviamos por correo electrónico cada vez que inicie sesión o realice acciones sensibles. Revise su correo electrónico para encontrar el código de 6 dígitos y completar la configuración.',
'form' => [
'code' => [
'label' => 'Ingrese el código de 6 dígitos que le enviamos por correo electrónico',
'validation_attribute' => 'código',
'actions' => [
'resend' => [
'label' => 'Enviar un código nuevo por correo electrónico',
'notifications' => [
'resent' => [
'title' => 'Le hemos enviado un código nuevo por correo electrónico.',
],
],
],
],
'messages' => [
'invalid' => 'El código ingresado no es válido.',
],
],
],
'actions' => [
'submit' => [
'label' => 'Habilitar códigos de verificación por correo',
],
],
],
'notifications' => [
'enabled' => [
'title' => 'Se han habilitado los códigos de verificación por correo electrónico',
],
],
];
@@ -0,0 +1,12 @@
<?php
return [
'subject' => 'Aquí está su código de inicio de sesión',
'lines' => [
'Su código de inicio de sesión es: :code',
'Este código expirará en un minuto.|Este código expirará en :minutos minutos.',
],
];
@@ -0,0 +1,60 @@
<?php
return [
'management_schema' => [
'actions' => [
'label' => 'Códigos de verificación por correo electrónico',
'below_content' => 'Reciba un código temporal en su correo electrónico para verificar su identidad durante el inicio de sesión.',
'messages' => [
'enabled' => 'Habilitados',
'disabled' => 'Deshabilitados',
],
],
],
'login_form' => [
'label' => 'Envíar un código a su correo electrónico',
'code' => [
'label' => 'Ingrese el código de 6 dígitos que le enviamos por correo electrónico',
'validation_attribute' => 'código',
'actions' => [
'resend' => [
'label' => 'Enviar un código nuevo por correo electrónico',
'notifications' => [
'resent' => [
'title' => 'Le hemos enviado un código nuevo por correo electrónico.',
],
],
],
],
'messages' => [
'invalid' => 'El código ingresado no es válido.',
],
],
],
];
@@ -0,0 +1,19 @@
<?php
return [
'title' => 'Configurar la autenticación de dos factores (2FA)',
'heading' => 'Configura la autenticación de dos factores',
'subheading' => '2FA agrega una capa adicional de seguridad a su cuenta al requerir una segunda forma de verificación al iniciar sesión.',
'actions' => [
'continue' => [
'label' => 'Continuar',
],
],
];
@@ -0,0 +1,27 @@
<?php
return [
'actions' => [
'Hacer clic para',
'copy' => [
'label' => 'copiar',
],
'o',
'download' => [
'label' => 'descargar',
],
'todos los códigos a la vez.',
],
'messages' => [
'copied' => 'Copiados',
],
];
@@ -0,0 +1,16 @@
<?php
return [
'subject' => 'Su dirección de correo electrónico está siendo cambiada',
'lines' => [
'Hemos recibido una solicitud para cambiar la dirección de correo electrónico asociada a su cuenta. Se utilizó su contraseña para confirmar el cambio.',
'Una vez verificada, la nueva dirección de correo electrónico en su cuenta será: :email.',
'Usted puede bloquear el cambio antes de que se verifique haciendo clic en el botón de abajo.',
'Si usted no ha realizado esta solicitud, póngase en contacto con nosotros de inmediato.',
],
'action' => 'Bloquear cambio de correo',
];
@@ -16,10 +16,18 @@ return [
'password' => [
'label' => 'Nueva contraseña',
'validation_attribute' => 'contraseña',
],
'password_confirmation' => [
'label' => 'Confirmar nueva contraseña',
'validation_attribute' => 'confirmación de contraseña',
],
'current_password' => [
'label' => 'Contraseña actual',
'below_content' => 'Por seguridad, por favor confirme su contraseña para continuar.',
'validation_attribute' => 'contraseña actual',
],
'actions' => [
@@ -32,8 +40,17 @@ return [
],
'multi_factor_authentication' => [
'label' => 'Autenticación de dos factores (2FA)',
],
'notifications' => [
'email_change_verification_sent' => [
'title' => 'Solicitud de cambio de correo electrónico enviada',
'body' => 'Se ha enviado una solicitud para cambiar su dirección de correo electrónico a :email. Por favor, revise su correo para confirmar el cambio.',
],
'saved' => [
'title' => 'Cambios guardados',
],
@@ -43,6 +43,30 @@ return [
],
'multi_factor' => [
'heading' => 'Verifique su identidad',
'subheading' => 'Para continuar con el inicio de sesión, deberá verificar su identidad.',
'form' => [
'provider' => [
'label' => '¿Cómo le gustaría verificar?',
],
'actions' => [
'authenticate' => [
'label' => 'Confirmar inicio de sesión',
],
],
],
],
'messages' => [
'failed' => 'Estas credenciales no coinciden con nuestros registros.',
@@ -11,7 +11,7 @@
$renderHookScopes = $livewire?->getRenderHookScopes();
$maxContentWidth ??= (filament()->getMaxContentWidth() ?? Width::SevenExtraLarge);
if (! $maxContentWidth instanceof Width) {
if (is_string($maxContentWidth)) {
$maxContentWidth = Width::tryFrom($maxContentWidth) ?? $maxContentWidth;
}
@endphp
@@ -6,7 +6,7 @@
$renderHookScopes = $livewire?->getRenderHookScopes();
$maxContentWidth ??= (filament()->getSimplePageMaxContentWidth() ?? Width::Large);
if (! $maxContentWidth instanceof Width) {
if (is_string($maxContentWidth)) {
$maxContentWidth = Width::tryFrom($maxContentWidth) ?? $maxContentWidth;
}
@endphp
+1 -1
View File
@@ -1 +1 @@
function o({isSkippable:s,isStepPersistedInQueryString:i,key:n,startStep:r,stepQueryStringKey:h}){return{step:null,init(){this.$watch("step",()=>this.updateQueryString()),this.step=this.getSteps().at(r-1),this.autofocusFields()},requestNextStep:async function(){await this.$wire.callSchemaComponentMethod(n,"nextStep",{currentStepIndex:this.getStepIndex(this.step)})},goToNextStep(){let t=this.getStepIndex(this.step)+1;t>=this.getSteps().length||(this.step=this.getSteps()[t],this.autofocusFields(),this.scroll())},goToPreviousStep(){let t=this.getStepIndex(this.step)-1;t<0||(this.step=this.getSteps()[t],this.autofocusFields(),this.scroll())},scroll(){this.$nextTick(()=>{this.$refs.header.children[this.getStepIndex(this.step)].scrollIntoView({behavior:"smooth",block:"start"})})},autofocusFields(){this.$nextTick(()=>this.$refs[`step-${this.step}`].querySelector("[autofocus]")?.focus())},getStepIndex(t){let e=this.getSteps().findIndex(p=>p===t);return e===-1?0:e},getSteps(){return JSON.parse(this.$refs.stepsData.value)},isFirstStep(){return this.getStepIndex(this.step)<=0},isLastStep(){return this.getStepIndex(this.step)+1>=this.getSteps().length},isStepAccessible(t){return s||this.getStepIndex(this.step)>this.getStepIndex(t)},updateQueryString(){if(!i)return;let t=new URL(window.location.href);t.searchParams.set(h,this.step),history.replaceState(null,document.title,t.toString())}}}export{o as default};
function o({isSkippable:s,isStepPersistedInQueryString:i,key:r,startStep:h,stepQueryStringKey:n}){return{step:null,init(){this.$watch("step",()=>this.updateQueryString()),this.step=this.getSteps().at(h-1),this.autofocusFields()},async requestNextStep(){await this.$wire.callSchemaComponentMethod(r,"nextStep",{currentStepIndex:this.getStepIndex(this.step)})},goToNextStep(){let t=this.getStepIndex(this.step)+1;t>=this.getSteps().length||(this.step=this.getSteps()[t],this.autofocusFields(),this.scroll())},goToPreviousStep(){let t=this.getStepIndex(this.step)-1;t<0||(this.step=this.getSteps()[t],this.autofocusFields(),this.scroll())},scroll(){this.$nextTick(()=>{this.$refs.header.children[this.getStepIndex(this.step)].scrollIntoView({behavior:"smooth",block:"start"})})},autofocusFields(){this.$nextTick(()=>this.$refs[`step-${this.step}`].querySelector("[autofocus]")?.focus())},getStepIndex(t){let e=this.getSteps().findIndex(p=>p===t);return e===-1?0:e},getSteps(){return JSON.parse(this.$refs.stepsData.value)},isFirstStep(){return this.getStepIndex(this.step)<=0},isLastStep(){return this.getStepIndex(this.step)+1>=this.getSteps().length},isStepAccessible(t){return s||this.getStepIndex(this.step)>this.getStepIndex(t)},updateQueryString(){if(!i)return;let t=new URL(window.location.href);t.searchParams.set(n,this.step),history.replaceState(null,document.title,t.toString())}}}export{o as default};
@@ -16,7 +16,7 @@ export default function wizardSchemaComponent({
this.autofocusFields()
},
requestNextStep: async function () {
async requestNextStep() {
await this.$wire.callSchemaComponentMethod(key, 'nextStep', {
currentStepIndex: this.getStepIndex(this.step),
})
@@ -32,7 +32,7 @@ trait CanOpenUrl
? $this->evaluate($this->url, [
'state' => $state,
])
: null;
: $this->evaluate($this->url);
}
if ($this->hasStateBasedUrls()) {
@@ -312,7 +312,7 @@ trait HasState
// we need to dehydrate the child component containers while
// informing them that they are not dehydrated, so that their
// child components get removed from the state.
foreach ($this->getChildSchemas() as $childSchema) {
foreach ($this->getChildSchemas(withHidden: true) as $childSchema) {
$childSchema->dehydrateState($state, isDehydrated: false);
}
+1 -1
View File
File diff suppressed because one or more lines are too long
@@ -1,13 +1,13 @@
export default () => ({
toggle(event) {
this.$refs.panel.toggle(event)
this.$refs.panel?.toggle(event)
},
open(event) {
this.$refs.panel.open(event)
this.$refs.panel?.open(event)
},
close(event) {
this.$refs.panel.close(event)
this.$refs.panel?.close(event)
},
})
@@ -22,7 +22,7 @@
'padding' => $sizePadding,
])->filter()->toJson();
if (! ($width instanceof Width)) {
if (is_string($width)) {
$width = Width::tryFrom($width) ?? $width;
}
@endphp
@@ -50,8 +50,8 @@
$footerActionsAlignment = filled($footerActionsAlignment) ? (Alignment::tryFrom($footerActionsAlignment) ?? $footerActionsAlignment) : null;
}
if (! $width instanceof Width) {
$width = filled($width) ? (Width::tryFrom($width) ?? $width) : null;
if (is_string($width)) {
$width = Width::tryFrom($width) ?? $width;
}
$closeEventHandler = filled($id) ? '$dispatch(' . \Illuminate\Support\Js::from($closeEventName) . ', { id: ' . \Illuminate\Support\Js::from($id) . ' })' : 'close()';
+1 -1
View File
File diff suppressed because one or more lines are too long
@@ -123,7 +123,7 @@
}
& .fi-ta-header-cell-sort-btn {
@apply flex w-full items-center justify-start gap-x-1;
@apply flex w-full cursor-pointer items-center justify-start gap-x-1;
}
& .fi-icon {
@@ -77,7 +77,7 @@ export default ({
this.selectRecords(keys)
},
toggleSelectRecordsInGroup: async function (group) {
async toggleSelectRecordsInGroup(group) {
this.isLoading = true
if (this.areRecordsSelected(this.getRecordsInGroupOnPage(group))) {
@@ -192,7 +192,7 @@ export default ({
this.selectRecords([key])
},
selectAllRecords: async function () {
async selectAllRecords() {
if (!canTrackDeselectedRecords) {
this.isLoading = true
@@ -243,4 +243,6 @@ return [
],
'default_model_label' => 'registro',
];
@@ -1275,10 +1275,13 @@
}}
>
@if ($isColumnSortable)
<button
<span
aria-label="{{ trim(strip_tags($columnLabel)) }}"
type="button"
role="button"
tabindex="0"
wire:click="sortTable('{{ $columnName }}')"
x-on:keydown.enter.prevent.stop="$wire.sortTable('{{ $columnName }}')"
x-on:keydown.space.prevent.stop="$wire.sortTable('{{ $columnName }}')"
wire:loading.attr="disabled"
class="fi-ta-header-cell-sort-btn"
>
@@ -1291,7 +1294,7 @@
default => 'tables::header-cell.sort-button',
})
}}
</button>
</span>
@else
{{ $columnLabel }}
@endif
@@ -1775,7 +1778,7 @@
@elseif ($columnWrapperTag === 'button')
type
="button"
wire:click.stop.prevent="{{ $columnWireClickAction }}"
wire:click.prevent.stop="{{ $columnWireClickAction }}"
wire:loading.attr="disabled"
wire:target="{{ $columnWireClickAction }}"
@endif
+3 -2
View File
@@ -2,6 +2,7 @@
namespace Filament\Tables\Columns;
use BackedEnum;
use Filament\Forms\Components\Concerns\CanDisableOptions;
use Filament\Forms\Components\Concerns\CanSelectPlaceholder;
use Filament\Forms\Components\Concerns\HasEnum;
@@ -95,7 +96,7 @@ class SelectColumn extends Column implements Editable, HasEmbeddedView
wire:ignore.self
<?= $attributes->toHtml() ?>
>
<input type="hidden" value="<?= str($state)->replace('"', '\\"') ?>" x-ref="serverState" />
<input type="hidden" value="<?= str(($state instanceof BackedEnum) ? $state->value : $state)->replace('"', '\\"') ?>" x-ref="serverState" />
<div
x-bind:class="{
@@ -110,7 +111,7 @@ class SelectColumn extends Column implements Editable, HasEmbeddedView
theme: $store.theme,
}
"
x-on:click.stop.prevent=""
x-on:click.prevent.stop=""
class="fi-input-wrp"
>
<select
+7 -1
View File
@@ -91,7 +91,13 @@ foreach (json_decode(file_get_contents('composer.json'), true)['require'] as $pa
continue;
}
$requireCommands[] = "composer require {$package}:\"^4.0\" -W --no-update";
$isWindowsPowershell = str_starts_with(php_uname(), 'Windows');
if (! $isWindowsPowershell) {
$requireCommands[] = "composer require {$package}:\"^4.0\" -W --no-update";
} else {
$requireCommands[] = "composer require '\"{$package}:^4.0\"' -W --no-update";
}
}
$requireCommands = implode("</strong><br /><strong>", $requireCommands);
@@ -84,7 +84,7 @@ class SimpleMethodChangesRector extends AbstractRector
'getRelativeRouteName' => $prependPanelParamModifier,
'getSlug' => $prependNullablePanelParamModifier,
'prependClusterSlug' => $prependPanelParamModifier,
'prependClusterBaseName' => $prependPanelParamModifier,
'prependClusterRouteBaseName' => $prependPanelParamModifier,
],
],
[
+3
View File
@@ -19,6 +19,9 @@ use Rector\Renaming\ValueObject\MethodCallRename;
use Rector\Renaming\ValueObject\RenameProperty;
return static function (RectorConfig $rectorConfig): void {
$rectorConfig->importNames();
$rectorConfig->importShortClasses();
$rectorConfig->ruleWithConfiguration(
RenameClassRector::class,
[
@@ -0,0 +1,13 @@
<?php
return [
'actions' => [
'filter' => [
'label' => 'Filtrar',
],
],
];
+24
View File
@@ -702,6 +702,30 @@ test('hidden components are not excluded from state dehydration if there is anot
->getState()->not()->toBe([]);
});
test('components in a hidden parent component with a grandparent component with a state path are excluded from state dehydration', function (): void {
$schema = Schema::make(Livewire::make())
->statePath('data')
->components([
(new Component)
->statePath('data')
->schema([
(new Component)
->schema([
(new Component)
->statePath(Str::random())
->default(Str::random()),
])
->hidden(),
]),
])
->fill();
invade($schema->getLivewire())->cacheSchema('form', $schema);
expect($schema)
->getState()->toBe(['data' => null]);
});
test('disabled components are excluded from state dehydration', function (): void {
$schema = Schema::make(Livewire::make())
->statePath('data')