app: Swap to using dioxus instead of yew
This commit is contained in:
parent
02a4187c39
commit
c80cc99255
29 changed files with 3558 additions and 3639 deletions
231
app/src/bootstrap/mod.rs
Normal file
231
app/src/bootstrap/mod.rs
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
use dioxus::prelude::*;
|
||||
use dioxus_class::prelude::*;
|
||||
|
||||
pub mod bs {
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(js_namespace = bootstrap)]
|
||||
extern "C" {
|
||||
pub type Modal;
|
||||
|
||||
#[wasm_bindgen(static_method_of = Modal, js_name = "getInstance")]
|
||||
pub fn get_instance(selector: &str) -> Modal;
|
||||
|
||||
#[wasm_bindgen(static_method_of = Modal, js_name = "getOrCreateInstance")]
|
||||
pub fn get_or_create_instance(selector: &str) -> Modal;
|
||||
|
||||
#[wasm_bindgen(method)]
|
||||
pub fn hide(this: &Modal);
|
||||
|
||||
#[wasm_bindgen(method)]
|
||||
pub fn show(this: &Modal);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn Spinner(cx: Scope) -> Element {
|
||||
cx.render(rsx! {
|
||||
div { class: "spinner-border", role: "status", span { class: "visually-hidden", "Loading" } }
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Props)]
|
||||
pub struct ModalContentProps<'a> {
|
||||
pub children: Element<'a>,
|
||||
}
|
||||
|
||||
pub fn ModalHeader<'a>(cx: Scope<'a, ModalContentProps<'a>>) -> Element {
|
||||
cx.render(rsx! {
|
||||
div { class: "modal-header", &cx.props.children }
|
||||
})
|
||||
}
|
||||
|
||||
pub fn ModalBody<'a>(cx: Scope<'a, ModalContentProps<'a>>) -> Element {
|
||||
cx.render(rsx! {
|
||||
div { class: "modal-body", &cx.props.children }
|
||||
})
|
||||
}
|
||||
|
||||
pub fn ModalFooter<'a>(cx: Scope<'a, ModalContentProps<'a>>) -> Element {
|
||||
cx.render(rsx! {
|
||||
div { class: "modal-footer", &cx.props.children }
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Props)]
|
||||
pub struct ModalProps<'a> {
|
||||
#[props(into)]
|
||||
pub id: String,
|
||||
#[props(default = false)]
|
||||
pub fade: bool,
|
||||
#[props(default = false)]
|
||||
pub centered: bool,
|
||||
#[props(into)]
|
||||
pub labeled_by: Option<String>,
|
||||
pub children: Element<'a>,
|
||||
}
|
||||
|
||||
pub fn Modal<'a>(cx: Scope<'a, ModalProps<'a>>) -> Element<'a> {
|
||||
let mut classes = Class::from(vec!["modal"]);
|
||||
|
||||
if cx.props.fade {
|
||||
classes.append("fade");
|
||||
}
|
||||
|
||||
let mut dialog_class = Class::from(vec!["modal-dialog"]);
|
||||
|
||||
if cx.props.centered {
|
||||
dialog_class.append("modal-dialog-centered");
|
||||
}
|
||||
|
||||
cx.render(rsx! {
|
||||
div { class: classes, id: cx.props.id.as_str(), tabindex: "-1", "aria-labelledby": cx.props.labeled_by.as_deref(), "aria-hidden": "true",
|
||||
div { class: dialog_class,
|
||||
div { class: "modal-content", &cx.props.children }
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Props)]
|
||||
pub struct TitledModalProps<'a> {
|
||||
#[props(into)]
|
||||
pub id: String,
|
||||
#[props(default = false)]
|
||||
pub fade: bool,
|
||||
#[props(default = false)]
|
||||
pub centered: bool,
|
||||
#[props(into)]
|
||||
pub title: String,
|
||||
pub children: Element<'a>,
|
||||
}
|
||||
|
||||
pub fn TitledModal<'a>(cx: Scope<'a, TitledModalProps<'a>>) -> Element {
|
||||
cx.render(rsx! {
|
||||
Modal {
|
||||
id: &cx.props.id,
|
||||
fade: cx.props.fade,
|
||||
centered: cx.props.centered,
|
||||
labeled_by: "{cx.props.id}Label",
|
||||
ModalHeader {
|
||||
h1 { class: "modal-title fs-5", id: "{cx.props.id}Label", cx.props.title.as_str() }
|
||||
button {
|
||||
"type": "button",
|
||||
class: "btn-close",
|
||||
"data-bs-dismiss": "modal",
|
||||
"aria-label": "Close"
|
||||
}
|
||||
}
|
||||
&cx.props.children
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Props)]
|
||||
pub struct FormModalProps<'a> {
|
||||
#[props(into)]
|
||||
pub id: String,
|
||||
#[props(default = false)]
|
||||
pub fade: bool,
|
||||
#[props(default = false)]
|
||||
pub centered: bool,
|
||||
#[props(into)]
|
||||
pub title: String,
|
||||
#[props(into, default = "Submit".into())]
|
||||
pub submit_label: String,
|
||||
pub on_submit: EventHandler<'a, FormEvent>,
|
||||
pub children: Element<'a>,
|
||||
}
|
||||
|
||||
pub fn FormModal<'a>(cx: Scope<'a, FormModalProps<'a>>) -> Element {
|
||||
cx.render(rsx! {
|
||||
TitledModal {
|
||||
id: &cx.props.id,
|
||||
fade: cx.props.fade,
|
||||
centered: cx.props.centered,
|
||||
title: &cx.props.title,
|
||||
ModalBody {
|
||||
form {
|
||||
id: "{cx.props.id}Form",
|
||||
prevent_default: "onsubmit",
|
||||
onsubmit: move |ev| cx.props.on_submit.call(ev),
|
||||
&cx.props.children
|
||||
}
|
||||
}
|
||||
ModalFooter {
|
||||
button {
|
||||
"type": "button",
|
||||
class: "btn btn-danger",
|
||||
"data-bs-dismiss": "modal",
|
||||
"Cancel"
|
||||
}
|
||||
button {
|
||||
"type": "submit",
|
||||
class: "btn btn-primary",
|
||||
form: "{cx.props.id}Form",
|
||||
cx.props.submit_label.as_str()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Props)]
|
||||
pub struct ConfirmDangerModalProps<'a> {
|
||||
#[props(into)]
|
||||
pub id: String,
|
||||
#[props(default = false)]
|
||||
pub fade: bool,
|
||||
#[props(default = false)]
|
||||
pub centered: bool,
|
||||
#[props(into)]
|
||||
pub title: String,
|
||||
pub on_confirm: EventHandler<'a, MouseEvent>,
|
||||
pub children: Element<'a>,
|
||||
}
|
||||
|
||||
pub fn ConfirmDangerModal<'a>(cx: Scope<'a, ConfirmDangerModalProps<'a>>) -> Element {
|
||||
cx.render(rsx! {
|
||||
TitledModal {
|
||||
id: &cx.props.id,
|
||||
fade: cx.props.fade,
|
||||
centered: cx.props.centered,
|
||||
title: &cx.props.title,
|
||||
ModalBody { &cx.props.children }
|
||||
ModalFooter {
|
||||
button {
|
||||
"type": "button",
|
||||
class: "btn btn-secondary",
|
||||
"data-bs-dismiss": "modal",
|
||||
"Cancel"
|
||||
}
|
||||
button {
|
||||
"type": "button",
|
||||
class: "btn btn-danger",
|
||||
"data-bs-dismiss": "modal",
|
||||
onclick: move |ev| cx.props.on_confirm.call(ev),
|
||||
"Confirm"
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Props)]
|
||||
pub struct ModalToggleProps<'a> {
|
||||
#[props(into)]
|
||||
pub class: String,
|
||||
#[props(into)]
|
||||
pub modal_id: String,
|
||||
pub children: Element<'a>,
|
||||
}
|
||||
|
||||
pub fn ModalToggleButton<'a>(cx: Scope<'a, ModalToggleProps<'a>>) -> Element {
|
||||
cx.render(rsx! {
|
||||
button {
|
||||
class: cx.props.class.as_str(),
|
||||
"data-bs-toggle": "modal",
|
||||
"data-bs-target": "#{cx.props.modal_id}",
|
||||
&cx.props.children
|
||||
}
|
||||
})
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue