Skip to content

Commit 3aa6e0d

Browse files
feat(shield-dioxus): add style (#128)
1 parent df4d5d1 commit 3aa6e0d

26 files changed

Lines changed: 227 additions & 132 deletions

File tree

Cargo.lock

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ serde_json = "1.0.133"
3636
shield = { path = "./packages/core/shield", version = "0.0.4" }
3737
shield-actix = { path = "./packages/integrations/shield-actix", version = "0.0.4" }
3838
shield-axum = { path = "./packages/integrations/shield-axum", version = "0.0.4" }
39+
shield-bootstrap = { path = "./packages/styles/shield-bootstrap", version = "0.0.4" }
3940
shield-credentials = { path = "./packages/methods/shield-credentials", version = "0.0.4" }
4041
shield-diesel = { path = "./packages/storage/shield-diesel", version = "0.0.4" }
4142
shield-dioxus = { path = "./packages/integrations/shield-dioxus", version = "0.0.4" }

examples/dioxus-axum/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ web = ["dioxus/web"]
3030
axum = { workspace = true, optional = true }
3131
dioxus = { workspace = true, features = ["router", "fullstack"] }
3232
shield.workspace = true
33+
shield-bootstrap = { workspace = true, features = ["dioxus"] }
3334
shield-dioxus.workspace = true
3435
shield-dioxus-axum = { workspace = true, optional = true }
3536
shield-memory = { workspace = true, optional = true }

examples/dioxus-axum/src/app.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use dioxus::prelude::*;
1+
use dioxus::{document::Stylesheet, prelude::*};
22
use shield_dioxus::ShieldRouter;
33

44
use crate::home::Home;
@@ -17,6 +17,12 @@ enum Route {
1717
#[component]
1818
pub fn App() -> Element {
1919
rsx! {
20+
Stylesheet {
21+
href: "https://cdn.jsdelivr.net/npm/bootstrap@5.3.7/dist/css/bootstrap.min.css",
22+
integrity: "sha384-LN+7fdVzj6u52u30Kp6M/trliBMCMKTyK833zpbD+pXdCLuTusPj697FH4R/5mcr",
23+
crossorigin: "anonymous"
24+
}
25+
2026
main {
2127
Router::<Route> {}
2228
}

examples/dioxus-axum/src/main.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ use crate::app::App;
55

66
#[cfg(not(feature = "server"))]
77
fn main() {
8-
dioxus::launch(App);
8+
use shield_bootstrap::dioxus::BootstrapStyle;
9+
10+
dioxus::LaunchBuilder::new()
11+
.with_context(BootstrapStyle::default().context())
12+
.launch(App)
913
}
1014

1115
#[cfg(feature = "server")]
@@ -19,7 +23,8 @@ async fn main() {
1923
prelude::{DioxusRouterExt, *},
2024
};
2125
use shield::{Shield, ShieldOptions};
22-
use shield_dioxus_axum::{ShieldLayer, provide_axum_integration};
26+
use shield_bootstrap::dioxus::BootstrapStyle;
27+
use shield_dioxus_axum::{DioxusAxumIntegration, ShieldLayer};
2328
use shield_memory::{MemoryStorage, User};
2429
use shield_oidc::{Keycloak, OidcMethod};
2530
use tokio::net::TcpListener;
@@ -61,7 +66,8 @@ async fn main() {
6166
let router = Router::new()
6267
.serve_dioxus_application(
6368
ServeConfigBuilder::new()
64-
.context_provider(provide_axum_integration::<User>)
69+
.context(DioxusAxumIntegration::<User>::default().context())
70+
.context(BootstrapStyle::default().context())
6571
.build()
6672
.unwrap(),
6773
App,

packages/core/shield/src/action.rs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ pub const SIGN_OUT_ACTION_ID: &str = "sign-out";
1515
pub trait Action<P: Provider>: ErasedAction + Send + Sync {
1616
fn id(&self) -> String;
1717

18-
fn render(&self, provider: P) -> Form;
18+
fn form(&self, provider: P) -> Form;
1919

2020
async fn call(
2121
&self,
@@ -29,7 +29,7 @@ pub trait Action<P: Provider>: ErasedAction + Send + Sync {
2929
pub trait ErasedAction: Send + Sync {
3030
fn erased_id(&self) -> String;
3131

32-
fn erased_render(&self, provider: Box<dyn Any + Send + Sync>) -> Form;
32+
fn erased_form(&self, provider: Box<dyn Any + Send + Sync>) -> Form;
3333

3434
async fn erased_call(
3535
&self,
@@ -48,8 +48,8 @@ macro_rules! erased_action {
4848
self.id()
4949
}
5050

51-
fn erased_render(&self, provider: Box<dyn std::any::Any + Send + Sync>) -> $crate::Form {
52-
self.render(*provider.downcast().expect("TODO"))
51+
fn erased_form(&self, provider: Box<dyn std::any::Any + Send + Sync>) -> $crate::Form {
52+
self.form(*provider.downcast().expect("TODO"))
5353
}
5454

5555
async fn erased_call(
@@ -87,11 +87,8 @@ pub(crate) mod tests {
8787
TEST_ACTION_ID.to_owned()
8888
}
8989

90-
fn render(&self, _provider: TestProvider) -> Form {
91-
Form {
92-
inputs: vec![],
93-
attributes: None,
94-
}
90+
fn form(&self, _provider: TestProvider) -> Form {
91+
Form { inputs: vec![] }
9592
}
9693

9794
async fn call(

packages/core/shield/src/form.rs

Lines changed: 32 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,18 @@
1-
use std::collections::HashMap;
2-
31
use serde::{Deserialize, Serialize};
42

5-
/// HTML [attribute](https://html.spec.whatwg.org/multipage/syntax.html#attributes-2).
6-
#[derive(Clone, Debug, Deserialize, Serialize)]
7-
pub enum Attribute {
8-
Boolean(bool),
9-
String(String),
10-
}
11-
12-
/// HTML [form](https://html.spec.whatwg.org/multipage/forms.html#the-form-element).
133
#[derive(Clone, Debug, Deserialize, Serialize)]
144
pub struct Form {
155
pub inputs: Vec<Input>,
16-
pub attributes: Option<HashMap<String, Attribute>>,
176
}
187

19-
/// HTML [input](https://html.spec.whatwg.org/multipage/input.html#the-input-element).
208
#[derive(Clone, Debug, Deserialize, Serialize)]
219
pub struct Input {
2210
pub name: String,
2311
pub label: Option<String>,
2412
pub r#type: InputType,
2513
pub value: Option<String>,
26-
pub attributes: Option<HashMap<String, Attribute>>,
2714
}
2815

29-
/// HTML input [type](https://html.spec.whatwg.org/multipage/input.html#attr-input-type) and [attributes](https://html.spec.whatwg.org/multipage/input.html#input-type-attr-summary).
3016
#[derive(Clone, Debug, Deserialize, Serialize)]
3117
pub enum InputType {
3218
Button(InputTypeButton),
@@ -53,12 +39,38 @@ pub enum InputType {
5339
Week(InputTypeWeek),
5440
}
5541

56-
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
57-
pub struct InputTypeButton {
58-
pub popovertarget: Option<String>,
59-
pub popovertargetaction: Option<String>,
42+
impl InputType {
43+
pub fn as_str(&self) -> &'static str {
44+
match self {
45+
InputType::Button(_) => "button",
46+
InputType::Checkbox(_) => "checkbox",
47+
InputType::Color(_) => "color",
48+
InputType::Date(_) => "date",
49+
InputType::DatetimeLocal(_) => "datetime-local",
50+
InputType::Email(_) => "email",
51+
InputType::File(_) => "file",
52+
InputType::Hidden(_) => "hidden",
53+
InputType::Image(_) => "image",
54+
InputType::Month(_) => "month",
55+
InputType::Number(_) => "number",
56+
InputType::Password(_) => "password",
57+
InputType::Radio(_) => "radio",
58+
InputType::Range(_) => "range",
59+
InputType::Reset(_) => "reset",
60+
InputType::Search(_) => "search",
61+
InputType::Submit(_) => "submit",
62+
InputType::Tel(_) => "tel",
63+
InputType::Text(_) => "text",
64+
InputType::Time(_) => "time",
65+
InputType::Url(_) => "url",
66+
InputType::Week(_) => "week",
67+
}
68+
}
6069
}
6170

71+
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
72+
pub struct InputTypeButton {}
73+
6274
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
6375
pub struct InputTypeCheckbox {
6476
pub checked: Option<bool>,
@@ -98,7 +110,6 @@ pub struct InputTypeDatetimeLocal {
98110
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
99111
pub struct InputTypeEmail {
100112
pub autocomplete: Option<String>,
101-
pub dirname: Option<String>,
102113
pub list: Option<String>,
103114
pub maxlength: Option<String>,
104115
pub minlength: Option<String>,
@@ -120,21 +131,13 @@ pub struct InputTypeFile {
120131
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
121132
pub struct InputTypeHidden {
122133
pub autocomplete: Option<String>,
123-
pub dirname: Option<String>,
124134
pub required: Option<bool>,
125135
}
126136

127137
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
128138
pub struct InputTypeImage {
129139
pub alt: Option<String>,
130-
pub formaction: Option<String>,
131-
pub formenctype: Option<String>,
132-
pub formmethod: Option<String>,
133-
pub formnovalidate: Option<bool>,
134-
pub formtarget: Option<String>,
135140
pub height: Option<String>,
136-
pub popovertarget: Option<String>,
137-
pub popovertargetaction: Option<String>,
138141
pub src: Option<String>,
139142
pub width: Option<String>,
140143
}
@@ -165,7 +168,6 @@ pub struct InputTypeNumber {
165168
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
166169
pub struct InputTypePassword {
167170
pub autocomplete: Option<String>,
168-
pub dirname: Option<String>,
169171
pub maxlength: Option<String>,
170172
pub minlength: Option<String>,
171173
pub pattern: Option<String>,
@@ -191,15 +193,11 @@ pub struct InputTypeRange {
191193
}
192194

193195
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
194-
pub struct InputTypeReset {
195-
pub popovertarget: Option<String>,
196-
pub popovertargetaction: Option<String>,
197-
}
196+
pub struct InputTypeReset {}
198197

199198
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
200199
pub struct InputTypeSearch {
201200
pub autocomplete: Option<String>,
202-
pub dirname: Option<String>,
203201
pub list: Option<String>,
204202
pub maxlength: Option<String>,
205203
pub minlength: Option<String>,
@@ -211,21 +209,11 @@ pub struct InputTypeSearch {
211209
}
212210

213211
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
214-
pub struct InputTypeSubmit {
215-
pub dirname: Option<String>,
216-
pub formaction: Option<String>,
217-
pub formenctype: Option<String>,
218-
pub formmethod: Option<String>,
219-
pub formnovalidate: Option<bool>,
220-
pub formtarget: Option<String>,
221-
pub popovertarget: Option<String>,
222-
pub popovertargetaction: Option<String>,
223-
}
212+
pub struct InputTypeSubmit {}
224213

225214
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
226215
pub struct InputTypeTel {
227216
pub autocomplete: Option<String>,
228-
pub dirname: Option<String>,
229217
pub list: Option<String>,
230218
pub maxlength: Option<String>,
231219
pub minlength: Option<String>,
@@ -239,7 +227,6 @@ pub struct InputTypeTel {
239227
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
240228
pub struct InputTypeText {
241229
pub autocomplete: Option<String>,
242-
pub dirname: Option<String>,
243230
pub list: Option<String>,
244231
pub maxlength: Option<String>,
245232
pub minlength: Option<String>,
@@ -264,7 +251,6 @@ pub struct InputTypeTime {
264251
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
265252
pub struct InputTypeUrl {
266253
pub autocomplete: Option<String>,
267-
pub dirname: Option<String>,
268254
pub list: Option<String>,
269255
pub maxlength: Option<String>,
270256
pub minlength: Option<String>,

packages/core/shield/src/shield.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::{any::Any, collections::HashMap, sync::Arc};
33
use futures::future::try_join_all;
44

55
use crate::{
6-
Form, error::ShieldError, method::ErasedMethod, options::ShieldOptions, storage::Storage,
6+
error::ShieldError, form::Form, method::ErasedMethod, options::ShieldOptions, storage::Storage,
77
user::User,
88
};
99

@@ -73,7 +73,8 @@ impl<U: User> Shield<U> {
7373
};
7474

7575
for provider in method.erased_providers().await? {
76-
let form = action.erased_render(provider);
76+
let form = action.erased_form(provider);
77+
7778
forms.push(form);
7879
}
7980
}
@@ -85,7 +86,7 @@ impl<U: User> Shield<U> {
8586
#[cfg(test)]
8687
mod tests {
8788
use crate::{
88-
ShieldOptions,
89+
options::ShieldOptions,
8990
storage::tests::{TEST_STORAGE_ID, TestStorage},
9091
};
9192

packages/core/shield/src/shield_dyn.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::{any::Any, sync::Arc};
22

33
use async_trait::async_trait;
44

5-
use crate::{Form, error::ShieldError, shield::Shield, user::User};
5+
use crate::{error::ShieldError, form::Form, shield::Shield, user::User};
66

77
#[async_trait]
88
pub trait DynShield: Send + Sync {

packages/integrations/shield-dioxus-axum/src/integration.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ use shield_dioxus::{DioxusIntegration, DioxusIntegrationDyn};
99

1010
pub struct DioxusAxumIntegration<U: User>(PhantomData<U>);
1111

12+
impl<U: User + Clone + 'static> DioxusAxumIntegration<U> {
13+
pub fn context(self) -> DioxusIntegrationDyn {
14+
DioxusIntegrationDyn::new(self)
15+
}
16+
}
17+
1218
impl<U: User> Default for DioxusAxumIntegration<U> {
1319
fn default() -> Self {
1420
Self(Default::default())
@@ -29,7 +35,3 @@ impl<U: User + Clone + 'static> DioxusIntegration for DioxusAxumIntegration<U> {
2935
session
3036
}
3137
}
32-
33-
pub fn provide_axum_integration<U: User + Clone + 'static>() -> DioxusIntegrationDyn {
34-
DioxusIntegrationDyn::new(DioxusAxumIntegration::<U>::default())
35-
}

0 commit comments

Comments
 (0)