#leptos #popup #modal #web-framework #events #swal #sweetalert

leptos_sweetalert

Leptos 网页框架的 SweetAlert 非官方重制版

3 个稳定版本

1.0.2 2024年4月13日

#838 in 网页编程

27 每月下载量

MIT 许可证

280KB
673

Leptos 的 SweetAlert

SweetAlert 是一个用于在网页上创建漂亮弹出窗口的 JavaScript 库。

我的仓库是一个 crate,允许你在 Leptos 网页框架中使用类似功能。

注意:这不是官方版本。SweetAlert 团队没有创建此仓库。我只是想能够在 Leptos 中使用 SweetAlert,因此我尝试自己重新创建它。这并不完全相同。我没有简单地复制 CSS,而是自己编写的,因为我的目标不是完美复制 SweetAlert,而是简化那些想要类似功能的人的工作。它非常容易修改,如果你想自定义它,那么请随意将源文件和 CSS 文件复制到你的项目中。

如何使用

首先,你需要初始化事件处理器,允许用户使用 Escape 键关闭 Swal。它还负责限制弹出窗口内的焦点。

use leptos_sweetalert::*;

fn main() {
    Swal::init_key_handlers();
    // your leptos main function's body...
}

然后,使用 Swal 模块和它的 fire() 方法来显示一个弹出窗口

#[component]
fn App() -> impl IntoView {
    let confirm = move |_| {
        Swal::fire(SwalOptions {
            title: "This is a title",
            text: "This is some text",
            icon: SwalIcon::SUCCESS,
            confirm_button_text: "LETS GO",
            show_cancel_button: true,
            show_deny_button: true,
            ..SwalOptions::default()
        });
    };

    view! {
        <button on:click=confirm>Click to confirm</button>
    }
}

如上例所示,传递给 fire() 方法的选项是一个名为 SwalOptions 的结构体。你可能已经知道,结构体的所有字段在初始化时都必须有一个值。但是字段很多,非常不便。因此,SwalOptions 实现了 Default trait,其目的是为所有字段提供默认值。使用 .. 语法让 Rust 为你未指定的所有字段分配默认值。这些默认值与 SweetAlert 使用的相同。

上例显示的弹出窗口看起来像这样

Demo

注意:自首次创建此演示以来,弹出窗口的样式可能已有所改变。

有关如何使用此crate的更多信息,请参阅示例crates.io上的Rust文档。

样式

当然,没有样式,弹出窗口看起来不会很好。在styles中为您提供了默认样式和主题。请将样式表添加到您的index.html文件中

<!DOCTYPE html>
<html lang="en">
  <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">

      <!-- The core styles are necessary: -->
      <link data-trunk rel="scss" rel="stylesheet" href="../styles/sweetalert-core.scss" />
      <!-- This is an optional theme. By default you don't need this: -->
      <link data-trunk rel="scss" rel="stylesheet" href="../styles/sweetalert-theme-borderless.scss" />

      <title>SweetAlert for Leptos demo</title>
  </head>
  <body>
  </body>
</html>

SwalOptions的泛型类型

为了使开发人员更容易使用弹出窗口,SwalOptions结构是泛型的,这很重要

#[derive(Debug, Clone)]
pub struct SwalOptions<S = &'static str, I = SwalIcon>
where
    S: AsRef<str> + Clone + Default + leptos::IntoView,
    I: SwalIconLike + Default + Clone + Copy,
{
    // ...
}

这意味着Swal可以像这样打开

let some_title = String::from("This is a title");
Swal::fire(SwalOptions {
    // Choose between String or &str for the type of the text fields.
    // However you can't combine both in the same struct.
    title: some_title,
    icon: SwalIcon::SUCCESS,
    ..SwalOptions::default()
});

在上面的示例中,两个泛型类型都被推断出来(字符串类型,S,以及用于图标的I类型)。默认情况下,S的类型是&'static str,而I的类型是SwalIcon。遗憾的是,在Rust中,无法在不显式指定其中之一的情况下使用具有默认泛型参数的结构体。因此,如果您在没有图标的情况下显示弹出窗口,则必须使用此语法

// Here "&str" is the type used for the text fields.
// Use whatever type suits you as long as it respects the constraints defined above.
Swal::fire(SwalOptions::<&str> {
    title: "Hello",
    ..SwalOptions::default()
});

连续打开多个弹出窗口

您可以在用户在弹出窗口中按下按钮时调用一个函数,并且这个函数可以打开一个新的弹出窗口

#[component]
fn App() -> impl IntoView {
    let confirm = move |_| {
        Swal::fire(SwalOptions {
            title: "This is a title",
            text: "This is some text",
            icon: SwalIcon::SUCCESS,
            // pre_confirm gets executed when the user clicks on the Confirm button.
            // It's prefixed with "pre" because it gets executed before the
            // popup closes, not after (see the 'then' field in the doc on crates.io).
            pre_confirm: || {
                Swal::fire(SwalOptions::<&str> {
                    title: "Confirmed !",
                    ..SwalOptions::default()
                });
            },
            ..SwalOptions::default()
        });
    };

    view! {
        <button on:click=confirm>Click to confirm</button>
    }
}

您可以通过Swal::close()方法以编程方式关闭弹出窗口。在底层,Swal::fire()方法关闭弹出窗口,等待关闭动画完成,然后使用给定参数打开一个新的弹出窗口。因此,如果您打算打开一个新的弹出窗口,而已经有一个打开,那么...

不要这样做

// This would unsync the animations,
// leading to weird behavior:
Swal::close(None);
Swal::fire(SwalOptions {
    title: "Hello",
    icon: SwalIcon::SUCCESS,
    ..SwalOptions::default()
});

关于异步操作呢?

此crate不支持async/await,这意味着如果您想通过弹出窗口实现异步操作,则必须自行控制弹出窗口的生命周期。以下是一个示例

#[component]
fn App() -> impl IntoView {
    let confirm = move |_| {
        Swal::fire(SwalOptions {
            // By default, the Swal closes itself as soon as one of the buttons is pressed,
            // or if the user has either clicked on the backdrop or pressed the Escape key.
            // However, you can tell the popup to persist:
            auto_close: false,

            title: "This is a title",
            text: "This is some text",
            icon: SwalIcon::SUCCESS,
            confirm_button_text: "LETS GO",
            show_cancel_button: true,
            show_deny_button: true,
            pre_confirm: || {
                // Perform your asynchronous actions here...
                // ...
                //
                // Once you're done, you can manually close the popup.
                // You have to give a reason explaining why this popup is closing.
                // The result will then be passed to the `then` callback.
                // If you don't care about the result then just use `None`.
                //
                // Closing a popup without mentioning a result will not trigger the "then" callback.
                Swal::close(Some(SwalResult::confirmed()));
            },
            then: |result: SwalResult| {
                // this callback is called after `pre_confirm`,
                // only when the Swal is closing.
            },
            ..SwalOptions::default()
        });
    };

    view! {
        <button on:click=confirm>Click to confirm</button>
    }
}

要自定义执行异步操作时的弹出窗口行为,请注意存在一些有用的方法来帮助您实现这一点

关于输入呢?

SweetAlert允许您直接在弹出窗口中使用输入。到目前为止,此功能不支持与SweetAlert相同的方式。要使用输入,您必须自行构建组件并将其插入到弹出窗口中,方法是通过SwalOptionsbody字段。有一个很好的示例深入探讨了这一点。

关于Toast通知?

SweetAlert附带“Toast”通知,这些是在屏幕角落出现的小通知,通常持续几秒钟。此功能不包括在此crate中,也不会实现。如果您希望使用Toast通知,则已经有一个非常适合的crate:leptos_toaster

创建自己的图标

您可以创建自己的图标。在crates.io的文档中已经有了完整的解释。

可访问性考虑

弹出窗口遵循accede-web.com上指定的指南。

为确保焦点保持在弹出窗口中,弹出窗口内的所有可聚焦元素都必须匹配此CSS查询选择器

*:is(a[href], button, input, textarea, select, details):not([disabled]):not([aria-hidden=true]):not([inert]), [tabindex]:not([tabindex='-1'])

注意inert 属性不会按预期工作。如果您想使多个元素变为不活跃状态,请将属性应用到每个元素上,而不是共同的父元素。

注意,将“display”属性设置为“none”的元素也将被忽略。

贡献

我对Leptos以及Rust都相对较新,如果您想贡献力量,请随时参与。

许可证

MIT许可证

依赖项

~19–32MB
~508K SLoC