diff --git a/app/Console/Commands/DeleteLivewireTemporaryUpload.php b/app/Console/Commands/DeleteLivewireTemporaryUpload.php
new file mode 100644
index 00000000..4020265e
--- /dev/null
+++ b/app/Console/Commands/DeleteLivewireTemporaryUpload.php
@@ -0,0 +1,24 @@
+isProduction()) {
+ return;
+ }
+
+ $this->components->info('The temporary upload folder of Livewire has been deleted.');
+ }
+}
diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php
index e71e8802..72e9cc79 100644
--- a/app/Console/Kernel.php
+++ b/app/Console/Kernel.php
@@ -2,6 +2,7 @@
namespace App\Console;
+use App\Console\Commands\DeleteLivewireTemporaryUpload;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
@@ -9,6 +10,11 @@ class Kernel extends ConsoleKernel
{
protected function schedule(Schedule $schedule): void
{
- // $schedule->command('inspire')->hourly();
+ $schedule->command(DeleteLivewireTemporaryUpload::class)->hourly();
+ }
+
+ protected function commands(): void
+ {
+ $this->load(__DIR__.'/Commands');
}
}
diff --git a/app/Enums/Example.php b/app/Enums/Example.php
index e5da18a5..fbd35540 100644
--- a/app/Enums/Example.php
+++ b/app/Enums/Example.php
@@ -13,6 +13,7 @@
use App\Enums\Examples\Form\Tag;
use App\Enums\Examples\Form\Textarea;
use App\Enums\Examples\Form\Toggle;
+use App\Enums\Examples\Form\Upload;
use App\Enums\Examples\Form\WithoutLivewire;
use App\Enums\Examples\Others\Alpine;
use App\Enums\Examples\Others\Configuration;
@@ -41,6 +42,7 @@
use App\Enums\Examples\Ui\Link;
use App\Enums\Examples\Ui\Loading;
use App\Enums\Examples\Ui\Modal;
+use App\Enums\Examples\Ui\Reaction;
use App\Enums\Examples\Ui\Select;
use App\Enums\Examples\Ui\Slide;
use App\Enums\Examples\Ui\Tab;
@@ -82,6 +84,7 @@ enum Example: string
case Pin = Pin::class;
case Radio = Radio::class;
case Range = Range::class;
+ case Reaction = Reaction::class;
case Select = Select::class;
case Slide = Slide::class;
case SoftPersonalization = SoftPersonalization::class;
@@ -95,6 +98,7 @@ enum Example: string
case Translation = Translation::class;
case Troubleshooting = Troubleshooting::class;
case Updates = Updates::class;
+ case Upload = Upload::class;
case Welcome = Welcome::class;
case WithoutLivewire = WithoutLivewire::class;
diff --git a/app/Enums/Examples/Form/Upload.php b/app/Enums/Examples/Form/Upload.php
new file mode 100644
index 00000000..a40b27a6
--- /dev/null
+++ b/app/Enums/Examples/Form/Upload.php
@@ -0,0 +1,148 @@
+
+ HTML;
+
+ public const LABEL_HINT_TIP = <<<'HTML'
+
+ HTML;
+
+ public const DELETE = <<<'HTML'
+
+
+
+
+
+
+
+ HTML;
+
+ public const DELETE_METHOD = <<<'HTML'
+ use Illuminate\Http\UploadedFile;
+
+ public function deleteUpload(string $originalName, string $temporaryName): void
+ {
+ // Change this for the name of the property
+ // that you are using to store the temporary files
+ if (!$this->photos) {
+ return;
+ }
+
+ $files = Arr::wrap($this->photos);
+
+ /** @var UploadedFile $file */
+ $file = collect($files)->filter(fn (UploadedFile $item) => $item->getFilename() === $temporaryName)->first();
+
+ // 1. Here we delete the file. Even if we have a error here, we simply
+ // ignore it because as long as the file is not persisted, it is
+ // temporary and will be deleted at some point if there is a failure here.
+ rescue(fn () => $file->delete(), report: false);
+
+ $collect = collect($files)->filter(fn (UploadedFile $item) => $item->getFilename() !== $temporaryName);
+
+ // 2. We guarantee restore of remaining files regardless of upload
+ // type, whether you are dealing with multiple or single uploads
+ $this->photos = is_array($this->photos) ? $collect->toArray() : $collect->first();
+ }
+ HTML;
+
+ public const MULTIPLE = <<<'HTML'
+
+
+
+ HTML;
+
+ public const MULTIPLE_BATCHES = <<<'HTML'
+ use Livewire\Component;
+ use Livewire\WithFileUploads;
+ use Illuminate\Http\UploadedFile;
+
+ class MyComponent extends Component
+ {
+ use WithFileUploads;
+
+ // For multiple files the property must be an array [tl! highlight:1]
+ public $photos = [];
+
+ // 1. We create a property that will temporarily store the uploaded files
+ public $backup = [];
+
+ public function updatingPhotos(): void
+ {
+ // 2. We store the uploaded files in the temporary property
+ $this->backup = $this->photos;
+ }
+
+ public function updatedPhotos(): void
+ {
+ if (!$this->photos) {
+ return;
+ }
+
+ // 3. We merge the newly uploaded files with the saved ones
+ $file = Arr::flatten(array_merge($this->backup, [$this->photos]));
+
+ // 4. We finishing by removing the duplicates
+ $this->photos = collect($file)->unique(fn (UploadedFile $item) => $item->getClientOriginalName())->toArray();
+ }
+ }
+ HTML;
+
+ public const MULTIPLE_BATCHES_OTHER_PROPERTIES = <<<'HTML'
+ // Supposing you want to use $files instead of $photos:
+
+ public $photos = []; // [tl! remove]
+ public $files = []; // [tl! add]
+
+ public function updatingPhotos(): void {} // [tl! remove]
+ public function updatingFiles(): void {} // [tl! add]
+
+ public function updatedPhotos(): void {} // [tl! remove]
+ public function updatedFiles(): void {} // [tl! add]
+ HTML;
+
+ public const ACCEPT = <<<'HTML'
+
+ HTML;
+
+ public const FOOTER_SLOT = <<<'HTML'
+
+
+
+ Save
+
+
+
+ HTML;
+
+ public const FOOTER_SLOT_WHEN_UPLOADED = <<<'HTML'
+
+ {{-- [tl! highlight] --}}
+
+ Save
+
+
+
+ HTML;
+
+ public const EVENTS = <<<'HTML'
+
+
+
+
+
+ HTML;
+
+ public const PERSONALIZATION = <<<'HTML'
+ TallStackUi::personalize()
+ ->form('upload')
+ ->block('block', 'classes');
+ HTML;
+}
diff --git a/app/Enums/Examples/Ui/Reaction.php b/app/Enums/Examples/Ui/Reaction.php
new file mode 100644
index 00000000..65bec05c
--- /dev/null
+++ b/app/Enums/Examples/Ui/Reaction.php
@@ -0,0 +1,93 @@
+
+ HTML;
+
+ public const BASIC = <<<'HTML'
+
+ HTML;
+
+ public const ANIMATED = <<<'HTML'
+
+ HTML;
+
+ public const POSITION = <<<'HTML'
+
+
+
+ HTML;
+
+ public const QUANTITY = <<<'HTML'
+
+ HTML;
+
+ public const QUANTITY_BIND = <<<'HTML'
+
+
+
+ HTML;
+
+ public const ONLY = <<<'HTML'
+
+
+
+ HTML;
+
+ public const SLOT = <<<'HTML'
+
+ React to the TallStackUI
+
+ HTML;
+
+ public const EVENTS = <<<'HTML'
+
+
+
+ HTML;
+
+ public const PERSONALIZATION = <<<'HTML'
+ TallStackUi::personalize()
+ ->reaction()
+ ->block('block', 'classes');
+ HTML;
+}
diff --git a/composer.json b/composer.json
index 6d96c2c0..4e378f21 100644
--- a/composer.json
+++ b/composer.json
@@ -13,7 +13,7 @@
"laravel/tinker": "^2.8",
"livewire/livewire": "^3.0",
"livewire/volt": "^1.0",
- "tallstackui/tallstackui": "^1.10",
+ "tallstackui/tallstackui": "^1.13",
"torchlight/torchlight-laravel": "^0.5.14"
},
"require-dev": {
diff --git a/composer.lock b/composer.lock
index 13a6e389..ffcef1e6 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "77a56bfd021459f391086e7cd39a481c",
+ "content-hash": "8b01efdf8009fa9d2f0dbf291cd5e880",
"packages": [
{
"name": "brick/math",
@@ -2204,16 +2204,16 @@
},
{
"name": "nesbot/carbon",
- "version": "2.72.1",
+ "version": "2.72.2",
"source": {
"type": "git",
"url": "https://github.com/briannesbitt/Carbon.git",
- "reference": "2b3b3db0a2d0556a177392ff1a3bf5608fa09f78"
+ "reference": "3e7edc41b58d65509baeb0d4a14c8fa41d627130"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/2b3b3db0a2d0556a177392ff1a3bf5608fa09f78",
- "reference": "2b3b3db0a2d0556a177392ff1a3bf5608fa09f78",
+ "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/3e7edc41b58d65509baeb0d4a14c8fa41d627130",
+ "reference": "3e7edc41b58d65509baeb0d4a14c8fa41d627130",
"shasum": ""
},
"require": {
@@ -2307,35 +2307,35 @@
"type": "tidelift"
}
],
- "time": "2023-12-08T23:47:49+00:00"
+ "time": "2024-01-19T00:21:53+00:00"
},
{
"name": "nette/schema",
- "version": "v1.2.5",
+ "version": "v1.3.0",
"source": {
"type": "git",
"url": "https://github.com/nette/schema.git",
- "reference": "0462f0166e823aad657c9224d0f849ecac1ba10a"
+ "reference": "a6d3a6d1f545f01ef38e60f375d1cf1f4de98188"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nette/schema/zipball/0462f0166e823aad657c9224d0f849ecac1ba10a",
- "reference": "0462f0166e823aad657c9224d0f849ecac1ba10a",
+ "url": "https://api.github.com/repos/nette/schema/zipball/a6d3a6d1f545f01ef38e60f375d1cf1f4de98188",
+ "reference": "a6d3a6d1f545f01ef38e60f375d1cf1f4de98188",
"shasum": ""
},
"require": {
- "nette/utils": "^2.5.7 || ^3.1.5 || ^4.0",
- "php": "7.1 - 8.3"
+ "nette/utils": "^4.0",
+ "php": "8.1 - 8.3"
},
"require-dev": {
- "nette/tester": "^2.3 || ^2.4",
+ "nette/tester": "^2.4",
"phpstan/phpstan-nette": "^1.0",
- "tracy/tracy": "^2.7"
+ "tracy/tracy": "^2.8"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.2-dev"
+ "dev-master": "1.3-dev"
}
},
"autoload": {
@@ -2367,22 +2367,22 @@
],
"support": {
"issues": "https://github.com/nette/schema/issues",
- "source": "https://github.com/nette/schema/tree/v1.2.5"
+ "source": "https://github.com/nette/schema/tree/v1.3.0"
},
- "time": "2023-10-05T20:37:59+00:00"
+ "time": "2023-12-11T11:54:22+00:00"
},
{
"name": "nette/utils",
- "version": "v4.0.3",
+ "version": "v4.0.4",
"source": {
"type": "git",
"url": "https://github.com/nette/utils.git",
- "reference": "a9d127dd6a203ce6d255b2e2db49759f7506e015"
+ "reference": "d3ad0aa3b9f934602cb3e3902ebccf10be34d218"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nette/utils/zipball/a9d127dd6a203ce6d255b2e2db49759f7506e015",
- "reference": "a9d127dd6a203ce6d255b2e2db49759f7506e015",
+ "url": "https://api.github.com/repos/nette/utils/zipball/d3ad0aa3b9f934602cb3e3902ebccf10be34d218",
+ "reference": "d3ad0aa3b9f934602cb3e3902ebccf10be34d218",
"shasum": ""
},
"require": {
@@ -2453,9 +2453,9 @@
],
"support": {
"issues": "https://github.com/nette/utils/issues",
- "source": "https://github.com/nette/utils/tree/v4.0.3"
+ "source": "https://github.com/nette/utils/tree/v4.0.4"
},
- "time": "2023-10-29T21:02:13+00:00"
+ "time": "2024-01-17T16:50:36+00:00"
},
{
"name": "nikic/php-parser",
@@ -5651,16 +5651,16 @@
},
{
"name": "tallstackui/tallstackui",
- "version": "v1.12.4",
+ "version": "v1.13.0",
"source": {
"type": "git",
"url": "https://github.com/tallstackui/tallstackui.git",
- "reference": "1c28ec54e291bc1e20ca4daeca403fd259f752bb"
+ "reference": "9d153e4f73a939649cd9af81af06c0193d54c0c7"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/tallstackui/tallstackui/zipball/1c28ec54e291bc1e20ca4daeca403fd259f752bb",
- "reference": "1c28ec54e291bc1e20ca4daeca403fd259f752bb",
+ "url": "https://api.github.com/repos/tallstackui/tallstackui/zipball/9d153e4f73a939649cd9af81af06c0193d54c0c7",
+ "reference": "9d153e4f73a939649cd9af81af06c0193d54c0c7",
"shasum": ""
},
"require": {
@@ -5706,7 +5706,7 @@
"description": "TallStackUI is a powerful suite of Blade components that elevate your workflow of Livewire applications.",
"support": {
"issues": "https://github.com/tallstackui/tallstackui/issues",
- "source": "https://github.com/tallstackui/tallstackui/tree/v1.12.4"
+ "source": "https://github.com/tallstackui/tallstackui/tree/v1.13.0"
},
"funding": [
{
@@ -5714,7 +5714,7 @@
"type": "github"
}
],
- "time": "2024-01-17T04:06:37+00:00"
+ "time": "2024-01-23T14:59:26+00:00"
},
{
"name": "tijsverkoyen/css-to-inline-styles",
@@ -6501,16 +6501,16 @@
},
{
"name": "laravel/pint",
- "version": "v1.13.9",
+ "version": "v1.13.10",
"source": {
"type": "git",
"url": "https://github.com/laravel/pint.git",
- "reference": "e3e269cc5d874c8efd2dc7962b1c7ff2585fe525"
+ "reference": "e2b5060885694ca30ac008c05dc9d47f10ed1abf"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel/pint/zipball/e3e269cc5d874c8efd2dc7962b1c7ff2585fe525",
- "reference": "e3e269cc5d874c8efd2dc7962b1c7ff2585fe525",
+ "url": "https://api.github.com/repos/laravel/pint/zipball/e2b5060885694ca30ac008c05dc9d47f10ed1abf",
+ "reference": "e2b5060885694ca30ac008c05dc9d47f10ed1abf",
"shasum": ""
},
"require": {
@@ -6521,8 +6521,8 @@
"php": "^8.1.0"
},
"require-dev": {
- "friendsofphp/php-cs-fixer": "^3.47.0",
- "illuminate/view": "^10.40.0",
+ "friendsofphp/php-cs-fixer": "^3.47.1",
+ "illuminate/view": "^10.41.0",
"larastan/larastan": "^2.8.1",
"laravel-zero/framework": "^10.3.0",
"mockery/mockery": "^1.6.7",
@@ -6563,7 +6563,7 @@
"issues": "https://github.com/laravel/pint/issues",
"source": "https://github.com/laravel/pint"
},
- "time": "2024-01-16T17:39:29+00:00"
+ "time": "2024-01-22T09:04:15+00:00"
},
{
"name": "laravel/sail",
@@ -6870,29 +6870,29 @@
},
{
"name": "pestphp/pest",
- "version": "v2.31.0",
+ "version": "v2.32.0",
"source": {
"type": "git",
"url": "https://github.com/pestphp/pest.git",
- "reference": "3457841a9b124653edcfef1d5da24e6afe176f79"
+ "reference": "ac5d6c1f6754b4a6b4d16d825e5ebd4725a4f779"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/pestphp/pest/zipball/3457841a9b124653edcfef1d5da24e6afe176f79",
- "reference": "3457841a9b124653edcfef1d5da24e6afe176f79",
+ "url": "https://api.github.com/repos/pestphp/pest/zipball/ac5d6c1f6754b4a6b4d16d825e5ebd4725a4f779",
+ "reference": "ac5d6c1f6754b4a6b4d16d825e5ebd4725a4f779",
"shasum": ""
},
"require": {
"brianium/paratest": "^7.3.1",
- "nunomaduro/collision": "^7.10.0|^8.0.1",
+ "nunomaduro/collision": "^7.10.0|^8.1.0",
"nunomaduro/termwind": "^1.15.1|^2.0.0",
"pestphp/pest-plugin": "^2.1.1",
"pestphp/pest-plugin-arch": "^2.6.1",
"php": "^8.1.0",
- "phpunit/phpunit": "^10.5.5"
+ "phpunit/phpunit": "^10.5.7"
},
"conflict": {
- "phpunit/phpunit": ">10.5.5",
+ "phpunit/phpunit": ">10.5.7",
"sebastian/exporter": "<5.1.0",
"webmozart/assert": "<1.11.0"
},
@@ -6923,7 +6923,8 @@
"Pest\\Plugins\\Snapshot",
"Pest\\Plugins\\Verbose",
"Pest\\Plugins\\Version",
- "Pest\\Plugins\\Parallel"
+ "Pest\\Plugins\\Parallel",
+ "Pest\\Plugins\\JUnit"
]
},
"phpstan": {
@@ -6962,7 +6963,7 @@
],
"support": {
"issues": "https://github.com/pestphp/pest/issues",
- "source": "https://github.com/pestphp/pest/tree/v2.31.0"
+ "source": "https://github.com/pestphp/pest/tree/v2.32.0"
},
"funding": [
{
@@ -6974,7 +6975,7 @@
"type": "github"
}
],
- "time": "2024-01-11T15:33:20+00:00"
+ "time": "2024-01-20T13:48:00+00:00"
},
{
"name": "pestphp/pest-plugin",
@@ -7970,16 +7971,16 @@
},
{
"name": "phpunit/phpunit",
- "version": "10.5.5",
+ "version": "10.5.7",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
- "reference": "ed21115d505b4b4f7dc7b5651464e19a2c7f7856"
+ "reference": "e5c5b397a95cb0db013270a985726fcae93e61b8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/ed21115d505b4b4f7dc7b5651464e19a2c7f7856",
- "reference": "ed21115d505b4b4f7dc7b5651464e19a2c7f7856",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e5c5b397a95cb0db013270a985726fcae93e61b8",
+ "reference": "e5c5b397a95cb0db013270a985726fcae93e61b8",
"shasum": ""
},
"require": {
@@ -8051,7 +8052,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
- "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.5"
+ "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.7"
},
"funding": [
{
@@ -8067,7 +8068,7 @@
"type": "tidelift"
}
],
- "time": "2023-12-27T15:13:52+00:00"
+ "time": "2024-01-14T16:40:30+00:00"
},
{
"name": "pimple/pimple",
diff --git a/contents/on-this-page.json b/contents/on-this-page.json
index d794902e..fbe2b838 100644
--- a/contents/on-this-page.json
+++ b/contents/on-this-page.json
@@ -103,6 +103,15 @@
"5": "Masks",
"6": "Invalidate"
},
+ "docs.form.upload": {
+ "0": "Basic Usage",
+ "1": "Label & Hint & Tip",
+ "3": "Delete",
+ "4": "Multiple",
+ "5": "Restricting File Types",
+ "6": "Footer Slot",
+ "7": "Events"
+ },
"docs.ui.alert": {
"0": "Basic Usage",
"1": "Title",
@@ -261,6 +270,16 @@
"5": "Target & Delay Options",
"6": "Configurations"
},
+ "docs.ui.reaction": {
+ "0": "Concept",
+ "1": "Persist Reactions",
+ "3": "Basic Usage",
+ "4": "Animated Style",
+ "5": "Tooltip Position",
+ "6": "Quantity Slot",
+ "7": "Using Less Icons",
+ "8": "Slot"
+ },
"docs.ui.select": {
"Native": {
"prefix": true,
diff --git a/resources/views/components/layout/navigation/index.blade.php b/resources/views/components/layout/navigation/index.blade.php
index e28c7746..db806af8 100644
--- a/resources/views/components/layout/navigation/index.blade.php
+++ b/resources/views/components/layout/navigation/index.blade.php
@@ -77,6 +77,9 @@ class="hidden w-full lg:flex items-center text-sm leading-6 text-slate-400 round
+
+
+
@@ -121,6 +124,9 @@ class="hidden w-full lg:flex items-center text-sm leading-6 text-slate-400 round
+
+
+
diff --git a/resources/views/components/top-bar.blade.php b/resources/views/components/top-bar.blade.php
index c41e0e9a..d8a1ce6a 100644
--- a/resources/views/components/top-bar.blade.php
+++ b/resources/views/components/top-bar.blade.php
@@ -1,5 +1,8 @@
-
-
- Release 1.11.0 is here! 🎉 Password component has been improved receiving format and password generator.
+
+
+ Release 1.13.0 is here! 🎉 Say hello to the new components:
+ Form Upload
+ and
+ Reactions
diff --git a/resources/views/documentation/form/upload.blade.php b/resources/views/documentation/form/upload.blade.php
new file mode 100644
index 00000000..53c7aea2
--- /dev/null
+++ b/resources/views/documentation/form/upload.blade.php
@@ -0,0 +1,93 @@
+
+
+ Form Upload
+
+ v1.13
+
+
+
+ Form upload component.
+
+
+
+
+
+ Files can be uploaded through selection or drag-and-drop. Also, when
+ sending a png, jpg, jpeg or gif file, a preview is offered when clicking on the
+ file image. To disable the preview, simply pass the :preview="false" parameter
+ to the component.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ You can use this algorithm to be the base of the method of deleting temporary files.
+
+
+
+
+
+
+
+
+
+
+ If you have ever uploaded multiple files, you may have already encountered this issue: after selecting some files, if new files are selected they replace the selected ones with the new selected files, instead of merging them. To solve this problem and allow your user to select multiple files, in batches, you can use an algorithm like this:
+
+
+
+
+
+ The only thing to pay attention to with this approach is that real-time validations
+ may not work correctly to display validation errors linked to the correct files,
+ so if you want to use this strategy we suggest that you use a single validation
+ with properties bind with wire:model. Also, remember to update
+ the methods with the name of the property you are using to upload files,
+ following Livewire lifecycle hooks convention:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ You can use the when-uploaded parameter directly in the slot
+ to only render the slot as a file has been uploaded:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/views/documentation/ui/reaction.blade.php b/resources/views/documentation/ui/reaction.blade.php
new file mode 100644
index 00000000..af6514a0
--- /dev/null
+++ b/resources/views/documentation/ui/reaction.blade.php
@@ -0,0 +1,86 @@
+
+
+ Reaction
+
+ v1.13
+
+
+
+ Reaction component.
+
+
+
+
+
+
+ Version 1.13.0 of TallStackUI introduces a new component: Reaction.
+ In the modern world many applications have blogs, posts or articles. This
+ way they need to capture the reaction of their readers to feel how welcome
+ or hated that content was. The reaction component is the combination of
+ the Tooltip
+ component with emoji icons offered by the
+ Noto Emoji Animation project.
+
+
+
+
+ The logic for persisting the reaction in a database, such as SQL, SQLite or Redis (cache)
+ is up to its own algorithm. If, for example, you don't create logic, especially one that
+ blocks many reactions from the same authenticated user, the user will react unlimitedly.
+ When an emoji is pressed, the react method is triggered, receiving the name of the reaction
+ as a parameter.
+
+
+
+
You can change the method that will receive the reaction using the react-method parameter directly in the component:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
You can bind a property for real-time updates:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/views/livewire/documentation/form/upload/single.blade.php b/resources/views/livewire/documentation/form/upload/single.blade.php
new file mode 100644
index 00000000..7cc65c35
--- /dev/null
+++ b/resources/views/livewire/documentation/form/upload/single.blade.php
@@ -0,0 +1,67 @@
+model === 3 ? 'photo3' : 'photo7';
+
+ if (!$this->{$property}) {
+ return;
+ }
+
+ $files = Arr::wrap($this->{$property});
+
+ /** @var UploadedFile $file */
+ $file = collect($files)->filter(fn(UploadedFile $item) => $item->getFilename() === $temporary)->first();
+
+ rescue(fn() => $file->delete(), report: false);
+
+ $collect = collect($files)->filter(fn(UploadedFile $item) => $item->getFilename() !== $temporary);
+
+ $this->{$property} = is_array($this->{$property}) ? $collect->toArray() : $collect->first();
+ }
+} ?>
+
+
+ @if ($model === 1)
+
+ @elseif ($model === 2)
+
+ @elseif ($model === 3)
+
+ @elseif ($model === 4)
+
+ @elseif ($model === 5)
+
+ @elseif ($model === 6)
+
+
+
+ Save
+
+
+
+ @elseif ($model === 7)
+
+ @endif
+
diff --git a/resources/views/livewire/documentation/personalization.blade.php b/resources/views/livewire/documentation/personalization.blade.php
index 141aa29e..992cd73d 100644
--- a/resources/views/livewire/documentation/personalization.blade.php
+++ b/resources/views/livewire/documentation/personalization.blade.php
@@ -67,6 +67,7 @@ public function content(string $block, string $class): void
Example:
+ The soft personalization should be done in boot method of service providers.
@endif
@if ($blocks)
diff --git a/resources/views/livewire/documentation/ui/reaction.blade.php b/resources/views/livewire/documentation/ui/reaction.blade.php
new file mode 100644
index 00000000..3f3a381d
--- /dev/null
+++ b/resources/views/livewire/documentation/ui/reaction.blade.php
@@ -0,0 +1,48 @@
+toast()
+ ->success('Success', 'You reacted with ' . $reaction)
+ ->send();
+
+ $this->quantity++;
+ }
+
+ public function wow(string $reaction): void
+ {
+ $this->toast()
+ ->success('🚀🚀🚀', 'TallStackUI is the best UI library!')
+ ->send();
+ }
+} ?>
+
+
+ @if ($model === 1)
+
+ @elseif ($model === 2)
+
+ @elseif ($model === 3)
+
+ @elseif ($model === 4)
+
+ @elseif ($model === 5)
+
+ @elseif ($model === 6)
+
+ React to the TallStackUI
+
+ @elseif ($model === 7)
+
+ @endif
+
diff --git a/routes/web.php b/routes/web.php
index f929ccd9..cda16bae 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -32,6 +32,7 @@
Route::view('/toggle', 'documentation.form.toggle', Example::Toggle->variables())->name('toggle');
Route::view('/range', 'documentation.form.range', Example::Range->variables())->name('range');
Route::view('/pin', 'documentation.form.pin', Example::Pin->variables())->name('pin');
+ Route::view('/upload', 'documentation.form.upload', Example::Upload->variables())->name('upload');
});
Route::prefix('/ui')
@@ -55,6 +56,7 @@
Route::view('/modal', 'documentation.ui.modal', Example::Modal->variables())->name('modal');
Route::view('/link', 'documentation.ui.link', Example::Link->variables())->name('link');
Route::view('/loading', 'documentation.ui.loading', Example::Loading->variables())->name('loading');
+ Route::view('/reaction', 'documentation.ui.reaction', Example::Reaction->variables())->name('reaction');
Route::view('/select', 'documentation.ui.select', Example::Select->variables())->name('select');
Route::view('/slide', 'documentation.ui.slide', Example::Slide->variables())->name('slide');
Route::view('/tab', 'documentation.ui.tab', Example::Tab->variables())->name('tab');
diff --git a/tests/Feature/StructureTest.php b/tests/Feature/StructureTest.php
index 03148fdd..36a32366 100644
--- a/tests/Feature/StructureTest.php
+++ b/tests/Feature/StructureTest.php
@@ -36,6 +36,7 @@
fn () => route('documentation.form.toggle'),
fn () => route('documentation.form.range'),
fn () => route('documentation.form.pin'),
+ fn () => route('documentation.form.upload'),
//
fn () => route('documentation.ui.alert'),
fn () => route('documentation.ui.avatar'),
@@ -50,6 +51,7 @@
fn () => route('documentation.ui.modal'),
fn () => route('documentation.ui.link'),
fn () => route('documentation.ui.loading'),
+ fn () => route('documentation.ui.reaction'),
fn () => route('documentation.ui.select'),
fn () => route('documentation.ui.slide'),
fn () => route('documentation.ui.tab'),