masmerise/livewire-toaster

为 Laravel / Livewire 提供美观的 toast 通知。

2.3.1 2024-07-21 10:39 UTC

This package is auto-updated.

Last update: 2024-09-21 13:17:10 UTC


README

Toaster Banner

为 Livewire 提供美观的 toast 通知

Latest Version on Packagist GitHub Tests Action Status Total Downloads

Toast 为在您的 Livewire 驱动的 Laravel 应用中显示 toast 通知提供了一个无缝的体验。

与其他许多 toast 实现(例如,您可以在其中轻松地从标准 Controller 或 Livewire Component 发送 toast 通知。您不需要考虑将“闪存”事物到会话或从您的 Livewire 组件中“派发浏览器事件”。只需派发您的 toast,Toast 将相应地路由消息。

展示

Toaster Demo

兼容性

* 功能齐全

内容

寻找 v1 文档? 点击这里.

安装

您可以通过 composer 安装此包

composer require masmerise/livewire-toaster

您可以发布包的配置文件

php artisan vendor:publish --tag=toaster-config

这是 toaster.php 配置文件的内容

return [

    /**
     * Add an additional second for every 100th word of the toast messages.
     *
     * Supported: true | false
     */
    'accessibility' => true,

    /**
     * The vertical alignment of the toast container.
     *
     * Supported: "bottom", "middle" or "top"
     */
    'alignment' => 'bottom',

    /**
     * Allow users to close toast messages prematurely.
     *
     * Supported: true | false
     */
    'closeable' => true,

    /**
     * The on-screen duration of each toast.
     *
     * Minimum: 3000 (in milliseconds)
     */
    'duration' => 3000,

    /**
     * The horizontal position of each toast.
     *
     * Supported: "center", "left" or "right"
     */
    'position' => 'right',

    /**
     * Whether messages passed as translation keys should be translated automatically.
     *
     * Supported: true | false
     */
    'translate' => true,
];

准备您的模板

接下来,您需要在您的 master 模板中使用 <x-toaster-hub /> 组件,以开始监听传入的 toast

<!DOCTYPE html>
<html>
<head>
    <!-- ... -->
</head>

<body>
    <!-- Application content -->

    <x-toaster-hub /> <!-- 👈 -->
</body>
</html>

配置脚本

之后,您需要在 resources/js/app.js 包中导入 Toaster 以开始监听传入的 toast

import './bootstrap';
import '../../vendor/masmerise/livewire-toaster/resources/js'; // 👈

// other app stuff...

Tailwind 样式

注意

如果您要自定义 Toast 的默认视图,请跳过此步骤。

Toast 提供了一个最小视图,该视图利用了 Tailwind CSS 的默认值。

如果默认 toast 外观满足您的需求,您需要将其注册到 Tailwind 的 purge 列表中

module.exports = {
    content: [
        './resources/**/*.blade.php',
        './vendor/masmerise/livewire-toaster/resources/views/*.blade.php', // 👈
    ],
}

否则,请参阅 视图定制

RTL 支持

注意

LTR 将默认,无论您是否应用了 ltr 属性。

如果您的应用使用的是 RTL 语言,例如阿拉伯语和希伯来语,不要忘记在文档根处添加 rtl 属性

<!DOCTYPE html>
<html dir="rtl"> <!-- 👈 -->
    ...
</html>

这将确保 UI 元素(如关闭按钮)被翻转,文本被正确对齐。

使用方法

从后端发送 toast

注意

Toaster 支持同时发送多个 toast,您不仅限于发送单个 toast。

Toaster

发送 toast 消息的标准推荐方法是使用 Toaster 门面。

use Masmerise\Toaster\Toaster;

final class RegistrationForm extends Component
{
    public function submit(): void
    {
        $this->validate();
        
        User::create($this->form);
        
        Toaster::success('User created!'); // 👈
    }
}

如果您需要细粒度控制,您始终可以直接使用 PendingToast 类来调用 Toaster 的方法

use Masmerise\Toaster\PendingToast;

final class RegistrationForm extends Component
{
    public function submit(): void
    {
        $this->validate();
        
        $user = User::create($this->form);
        
        // 👇
        PendingToast::create()
            ->when($user->isAdmin(),
                fn (PendingToast $toast) => $toast->message('Admin created')
            )
            ->unless($user->isAdmin(),
                fn (PendingToast $toast) => $toast->message('User created')
            )
            ->success();
    }
}

Toastable

您可以使任何类 Toastable 从中发送 toast

use Masmerise\Toaster\Toastable;

final class ProductListing extends Component
{
    use Toastable; // 👈

    public function check(): void
    {
        $result = Product::query()
            ->tap(new Available())
            ->count();
            
        if ($result < 5) {
            $this->warning('The quantity on hand is critically low.'); // 👈
        }
    }
}

重定向

每当您从应用中的任何地方返回 RedirectResponse 时,您可以将任何 Toaster 方法链接到发送 toast 消息

final class CompanyController extends Controller
{
    /** @throws ValidationException */
    public function store(Request $request): RedirectResponse
    {
        $validator = Validator::make($request->all(), [...]);
        
        if ($validator->fails()) {
            return Redirect::back()
                ->error('The form contains several errors'); // 👈
        }
    
        Company::create($validator->validate());
        
        return Redirect::route('dashboard')
            ->info('Company created!'); // 👈
    }
}

当然,这不仅仅限于 Controller,您也可以在 Livewire Component 中进行重定向。

依赖注入

如果您想保持“纯净”,您还可以注入 Collector 合同并使用 ToastBuilder 来发送 toast

use Masmerise\Toaster\Collector;
use Masmerise\Toaster\ToasterConfig;
use Masmerise\Toaster\ToastBuilder;

final readonly class SendEmailVerifiedNotification
{
    public function __construct(
        private ToasterConfig $config,
        private Collector $toasts,
    ) {}
    
    public function handle(Verified $event): void
    {
        $toast = ToastBuilder::create()
            ->duration($this->config->duration)
            ->success()
            ->message("Thank you, {$event->user->name}!")
            ->get();
            
        $this->toasts->collect($toast);
    }
}

从前端发送 toast

您可以从任何地方调用全局可用的 Toaster 实例来发送任何 toast 消息

<button @click="Toaster.success('Form submitted!')">
    Submit
</button>

可用方法: errorinfowarning 以及 success

自动翻译消息

注意

必须将 translate 配置值设置为 true

而不是这样做

Toaster::success(
    Lang::get('path.to.translation', ['replacement' => 'value'])
);

Toast 插件可以使您这样做

Toaster::success('path.to.translation', ['replacement' => 'value']);

您可以混合搭配,没有任何问题

Toaster::info('user.created', ['name' => $user->full_name]);
Toaster::info('You now have full access!');

您可以随时做任何想做的事情。

无障碍访问

注意

必须将 accessibility 配置值设置为 true

Toast 会在每 100 个单词中添加额外的 1 秒到屏幕上的显示时间。这样,您的用户将有足够的时间阅读比平常稍大的 Toast。

因此,如果您的基准持续时间值是 3 秒,并且您的 Toast 包含 223 个单词,Toast 的总屏幕持续时间将是 3 + 2 = 5 秒

单元测试

注意

如果您使用 自动翻译消息,您应该断言是否正确传递了 翻译键 而不是由 Laravel 的翻译器替换的易读消息。否则,由于单元测试期间消息没有翻译,您的测试将会失败。

Toaster 提供了一些测试功能,以便您构建一个健壮的应用程序

use Masmerise\Toaster\Toaster;

final class RegisterUserControllerTest extends TestCase
{
    #[Test]
    public function users_can_register(): void
    {
        // Arrange
        Toaster::fake();
        Toaster::assertNothingDispatched();
        
        // Act
        $response = $this->post('users', [ ... ]);
        
        // Assert
        $response->assertRedirect('profile');
        Toaster::assertDispatched('Welcome!');
    }
}

扩展行为

想象一下,您想要跟踪每天发送到管理员仪表板的 Toast 数量。首先,创建一个包含此逻辑的新类

final readonly class DailyCountingCollector implements Collector
{
    public function __construct(private Collector $next) {}

    public function collect(Toast $toast): void
    {
        // increment the counter on durable storage

        $this->next->collect($toast);
    }

    public function release(): array
    {
        return $this->next->release();
    }
}

然后,在您的 AppServiceProvider 中扩展行为

public function register(): void
{
    $this->app->extend(Collector::class, 
        static fn (Collector $next) => new DailyCountingCollector($next)
    );
}

就这样!

视图定制

虽然默认的 Toast 很漂亮,但它们可能不符合您的设计,您可能想自定义它们。

您可以通过发布 Toaster 的视图来实现这一点

php artisan vendor:publish --tag=toaster-views

hub.blade.php 视图将被发布到您应用程序的 resources/views/vendor/toaster 目录。您可以根据喜好自由修改任何内容。

可用 viewData

  • $alignment - 可以根据配置垂直对齐 Toast 容器
  • $closeable - 是否应该通过 Blade 组件渲染关闭按钮
  • $config - 默认配置值,由 Alpine 组件使用
  • $position - 可以根据配置定位 Toast
  • $toasts - Toaster 通过 Alpine 组件闪存到会话中的 Toast,由 Alpine 组件使用

警告

必须 保持 x-datax-init 指令,并且您 必须 继续使用 x-for 循环。否则,为 Toaster 提供动力的 Alpine 组件将开始出现故障。

测试

composer test

更新日志

请参阅 变更日志 了解最近的变化信息。

安全

如果您发现任何安全相关的问题,请通过电子邮件 support@muhammedsari.me 而不是使用问题跟踪器。

致谢

许可证

MIT 许可证 (MIT)。有关更多信息,请参阅 许可证文件