🐛 Fix duplicated class names in components

This commit is contained in:
Manuel Cillero 2023-09-09 07:52:50 +02:00
parent cb18e9a5c6
commit 64ec767a5f
5 changed files with 57 additions and 77 deletions

View file

@ -38,7 +38,7 @@ async fn demo(request: service::HttpRequest) -> ResultPage<Markup, FatalError> {
.with_context(ContextOp::AddStyleSheet(StyleSheet::at( .with_context(ContextOp::AddStyleSheet(StyleSheet::at(
"/homedemo/css/styles.css", "/homedemo/css/styles.css",
))) )))
.with_body_classes(ClassesOp::AddFirst, "default-homepage") .with_body_classes(ClassesOp::Add, "default-homepage")
.with_in("content", hello_world()) .with_in("content", hello_world())
.with_in("content", welcome()) .with_in("content", welcome())
.with_in("content", about_pagetop()) .with_in("content", about_pagetop())

View file

@ -30,7 +30,7 @@ impl ComponentTrait for Button {
fn new() -> Self { fn new() -> Self {
Button::default() Button::default()
.with_classes(ClassesOp::SetDefault, "btn btn-primary") .with_classes(ClassesOp::SetDefault, "btn btn-primary")
.with_classes(ClassesOp::AddFirst, "form-button") .with_classes(ClassesOp::Add, "form-button")
} }
fn handle(&self) -> Handle { fn handle(&self) -> Handle {
@ -76,7 +76,7 @@ impl Button {
pub fn submit(value: L10n) -> Self { pub fn submit(value: L10n) -> Self {
let mut button = Button::new() let mut button = Button::new()
.with_classes(ClassesOp::Replace("form-button"), "form-submit") .with_classes(ClassesOp::Replace("form-button".to_owned()), "form-submit")
.with_value(value); .with_value(value);
button.button_type = ButtonType::Submit; button.button_type = ButtonType::Submit;
button button
@ -84,7 +84,7 @@ impl Button {
pub fn reset(value: L10n) -> Self { pub fn reset(value: L10n) -> Self {
let mut button = Button::new() let mut button = Button::new()
.with_classes(ClassesOp::Replace("form-button"), "form-reset") .with_classes(ClassesOp::Replace("form-button".to_owned()), "form-reset")
.with_value(value); .with_value(value);
button.button_type = ButtonType::Reset; button.button_type = ButtonType::Reset;
button button

View file

@ -25,7 +25,7 @@ impl ComponentTrait for Date {
fn new() -> Self { fn new() -> Self {
Date::default() Date::default()
.with_classes(ClassesOp::SetDefault, "form-item") .with_classes(ClassesOp::SetDefault, "form-item")
.with_classes(ClassesOp::AddFirst, "form-type-date") .with_classes(ClassesOp::Add, "form-type-date")
} }
fn handle(&self) -> Handle { fn handle(&self) -> Handle {

View file

@ -43,7 +43,7 @@ impl ComponentTrait for Input {
fn new() -> Self { fn new() -> Self {
Input::default() Input::default()
.with_classes(ClassesOp::SetDefault, "form-item") .with_classes(ClassesOp::SetDefault, "form-item")
.with_classes(ClassesOp::AddFirst, "form-type-textfield") .with_classes(ClassesOp::Add, "form-type-textfield")
.with_size(Some(60)) .with_size(Some(60))
.with_maxlength(Some(128)) .with_maxlength(Some(128))
} }
@ -113,51 +113,46 @@ impl Input {
Input::new() Input::new()
} }
#[rustfmt::skip]
pub fn password() -> Self { pub fn password() -> Self {
let mut input = Input::new().with_classes( let mut input = Input::new().with_classes(
ClassesOp::Replace("form-type-textfield"), ClassesOp::Replace("form-type-textfield".to_owned()),
"form-type-password", "form-type-password",
); );
input.input_type = InputType::Password; input.input_type = InputType::Password;
input input
} }
#[rustfmt::skip]
pub fn search() -> Self { pub fn search() -> Self {
let mut input = Input::new().with_classes( let mut input = Input::new().with_classes(
ClassesOp::Replace("form-type-textfield"), ClassesOp::Replace("form-type-textfield".to_owned()),
"form-type-search", "form-type-search",
); );
input.input_type = InputType::Search; input.input_type = InputType::Search;
input input
} }
#[rustfmt::skip]
pub fn email() -> Self { pub fn email() -> Self {
let mut input = Input::new().with_classes( let mut input = Input::new().with_classes(
ClassesOp::Replace("form-type-textfield"), ClassesOp::Replace("form-type-textfield".to_owned()),
"form-type-email" "form-type-email",
); );
input.input_type = InputType::Email; input.input_type = InputType::Email;
input input
} }
#[rustfmt::skip]
pub fn telephone() -> Self { pub fn telephone() -> Self {
let mut input = Input::new().with_classes( let mut input = Input::new().with_classes(
ClassesOp::Replace("form-type-textfield"), ClassesOp::Replace("form-type-textfield".to_owned()),
"form-type-telephone", "form-type-telephone",
); );
input.input_type = InputType::Telephone; input.input_type = InputType::Telephone;
input input
} }
#[rustfmt::skip]
pub fn url() -> Self { pub fn url() -> Self {
let mut input = Input::new().with_classes( let mut input = Input::new().with_classes(
ClassesOp::Replace("form-type-textfield"), ClassesOp::Replace("form-type-textfield".to_owned()),
"form-type-url" "form-type-url",
); );
input.input_type = InputType::Url; input.input_type = InputType::Url;
input input

View file

@ -1,24 +1,22 @@
use crate::{concat_string, fn_builder}; use crate::fn_builder;
pub enum ClassesOp { pub enum ClassesOp {
Add, Add,
AddAfter(&'static str),
AddBefore(&'static str),
AddFirst,
Remove, Remove,
Replace(&'static str), Replace(String),
Reset, Reset,
SetDefault, SetDefault,
SetDefaultIfEmpty,
} }
#[rustfmt::skip] #[derive(Eq, PartialEq)]
#[derive(Default)] enum ClassType {
pub struct Classes { Default,
default: String, User,
added : String,
} }
#[derive(Default)]
pub struct Classes(Vec<(String, ClassType)>);
impl Classes { impl Classes {
pub fn new() -> Self { pub fn new() -> Self {
Classes::default() Classes::default()
@ -28,64 +26,49 @@ impl Classes {
#[fn_builder] #[fn_builder]
pub fn alter_value(&mut self, op: ClassesOp, classes: &str) -> &mut Self { pub fn alter_value(&mut self, op: ClassesOp, classes: &str) -> &mut Self {
let classes = classes.trim(); let classes: Vec<String> = classes
.split_ascii_whitespace()
.map(|c| c.to_owned())
.collect();
match op { match op {
ClassesOp::Add => { ClassesOp::Add => {
self.added = concat_string!(self.added, " ", classes).trim().to_owned() for class in classes {
if self.0.iter().position(|(c, _)| c.eq(&class)).is_none() {
self.0.push((class, ClassType::User));
} }
ClassesOp::AddAfter(class) => {
let mut v_added: Vec<&str> = self.added.split_ascii_whitespace().collect();
match v_added.iter().position(|c| c.eq(&class)) {
Some(pos) => v_added.insert(pos + 1, classes),
_ => v_added.push(classes),
} }
self.added = v_added.join(" ");
}
ClassesOp::AddBefore(class) => {
let mut v_added: Vec<&str> = self.added.split_ascii_whitespace().collect();
match v_added.iter().position(|c| c.eq(&class)) {
Some(pos) => v_added.insert(pos, classes),
_ => v_added.insert(0, classes),
}
self.added = v_added.join(" ");
}
ClassesOp::AddFirst => {
self.added = concat_string!(classes, " ", self.added).trim().to_owned()
} }
ClassesOp::Remove => { ClassesOp::Remove => {
let v_list: Vec<&str> = classes.split_ascii_whitespace().collect(); for class in classes {
let mut v_added: Vec<&str> = self.added.split_ascii_whitespace().collect(); self.0
for class in v_list { .retain(|(c, t)| c.ne(&class) || t.ne(&ClassType::User));
if let Some(pos) = v_added.iter().position(|c| c.eq(&class)) {
v_added.remove(pos);
} }
} }
self.added = v_added.join(" ");
}
ClassesOp::Replace(class) => { ClassesOp::Replace(value) => {
let mut v_added: Vec<&str> = self.added.split_ascii_whitespace().collect(); for class in classes {
match v_added.iter().position(|c| c.eq(&class)) { match self.0.iter().position(|(c, _)| c.eq(&value)) {
Some(pos) => { Some(pos) => {
v_added.remove(pos); self.0.remove(pos);
v_added.insert(pos, classes); self.0.insert(pos, (class, ClassType::User));
}
_ => self.0.push((class, ClassType::User)),
} }
_ => v_added.push(classes),
} }
self.added = v_added.join(" ");
} }
ClassesOp::Reset => self.added = classes.to_owned(), ClassesOp::Reset => self.0.retain(|(_, t)| t.eq(&ClassType::Default)),
ClassesOp::SetDefault => self.default = classes.to_owned(), ClassesOp::SetDefault => {
self.0.retain(|(_, t)| t.eq(&ClassType::User));
ClassesOp::SetDefaultIfEmpty => { let mut pos = 0;
if self.default.is_empty() { for class in classes {
self.default = classes.to_owned() if self.0.iter().position(|(c, _)| c.eq(&class)).is_none() {
self.0.insert(pos, (class, ClassType::Default));
pos = pos + 1;
}
} }
} }
} }
@ -95,13 +78,15 @@ impl Classes {
// Classes GETTERS. // Classes GETTERS.
pub fn get(&self) -> Option<String> { pub fn get(&self) -> Option<String> {
if self.default.is_empty() && self.added.is_empty() { if self.0.len() == 0 {
None None
} else { } else {
Some( Some(
concat_string!(self.default, " ", self.added) self.0
.trim() .iter()
.to_owned(), .map(|(c, _)| c.to_owned())
.collect::<Vec<String>>()
.join(" "),
) )
} }
} }