Re-factor props and attrs handling.
This commit is contained in:
parent
c6ba1f9b11
commit
6236cf6ae9
27 changed files with 604 additions and 500 deletions
|
@ -1,8 +1,10 @@
|
|||
use super::{Color, Edge};
|
||||
use crate::props::IntoBsClass;
|
||||
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub struct Border(pub Edge, pub Color);
|
||||
|
||||
impl super::BootstrapClass for Border {
|
||||
impl IntoBsClass for Border {
|
||||
fn as_classname(&self) -> String {
|
||||
let edge = match self.0 {
|
||||
Edge::All => "border".to_owned(),
|
||||
|
|
|
@ -34,3 +34,13 @@ impl Color {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_with_prefix() {
|
||||
assert_eq!(Color::Primary.with_prefix("alert"), "alert-primary");
|
||||
}
|
||||
}
|
||||
|
|
54
src/prelude/edge.rs
Normal file
54
src/prelude/edge.rs
Normal file
|
@ -0,0 +1,54 @@
|
|||
use std::fmt::{Display, Formatter, Result};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum Edge {
|
||||
All,
|
||||
Top,
|
||||
Right,
|
||||
Bottom,
|
||||
Left,
|
||||
LeftAndRight,
|
||||
TopAndBottom,
|
||||
}
|
||||
|
||||
impl Display for Edge {
|
||||
fn fmt(&self, fmt: &mut Formatter) -> Result {
|
||||
match self {
|
||||
Self::All => write!(fmt, ""),
|
||||
Self::Top => write!(fmt, "t"),
|
||||
Self::Bottom => write!(fmt, "b"),
|
||||
Self::Right => write!(fmt, "r"),
|
||||
Self::Left => write!(fmt, "l"),
|
||||
Self::LeftAndRight => write!(fmt, "x"),
|
||||
Self::TopAndBottom => write!(fmt, "y"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Edge {
|
||||
fn suffix(&self) -> &str {
|
||||
match self {
|
||||
Self::Top => "-top",
|
||||
_ => "",
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn with_prefix<S: AsRef<str>>(&self, prefix: S) -> String {
|
||||
match self {
|
||||
Self::All => prefix.as_ref().to_owned(),
|
||||
Self::LeftAndRight => format!(
|
||||
"{0}{1} {0}{2}",
|
||||
prefix.as_ref(),
|
||||
Self::Left.suffix(),
|
||||
Self::Right.suffix()
|
||||
),
|
||||
Self::TopAndBottom => format!(
|
||||
"{0}{1} {0}{2}",
|
||||
prefix.as_ref(),
|
||||
Self::Top.suffix(),
|
||||
Self::Bottom.suffix()
|
||||
),
|
||||
_ => format!("{}{}", prefix.as_ref(), self.suffix()),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,9 @@
|
|||
use crate::props::IntoBsClass;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct Margin(pub super::Edge, pub usize);
|
||||
|
||||
impl super::BootstrapClass for Margin {
|
||||
impl IntoBsClass for Margin {
|
||||
fn as_classname(&self) -> String {
|
||||
format!("m{}-{}", self.0, self.1)
|
||||
}
|
||||
|
|
|
@ -1,117 +1,12 @@
|
|||
mod border;
|
||||
mod color;
|
||||
mod edge;
|
||||
mod margin;
|
||||
mod padding;
|
||||
|
||||
pub use self::{border::Border, color::Color, margin::Margin, padding::Padding};
|
||||
use std::fmt::{Display, Formatter, Result};
|
||||
pub use self::{border::Border, color::Color, edge::Edge, margin::Margin, padding::Padding};
|
||||
use yew::prelude::*;
|
||||
|
||||
#[derive(Properties, Clone, PartialEq, Default)]
|
||||
pub struct Props {
|
||||
#[prop_or_default]
|
||||
pub aria_label: String,
|
||||
#[prop_or_default]
|
||||
pub role: String,
|
||||
#[prop_or_default]
|
||||
pub border: Option<Border>,
|
||||
#[prop_or_default]
|
||||
pub borders: Vec<Border>,
|
||||
#[prop_or_default]
|
||||
pub margin: Option<Margin>,
|
||||
#[prop_or_default]
|
||||
pub margins: Vec<Margin>,
|
||||
#[prop_or_default]
|
||||
pub padding: Option<Padding>,
|
||||
#[prop_or_default]
|
||||
pub paddings: Vec<Padding>,
|
||||
#[prop_or_default]
|
||||
pub class: String,
|
||||
#[prop_or_default]
|
||||
pub style: String,
|
||||
#[prop_or_default]
|
||||
pub children: Children,
|
||||
}
|
||||
|
||||
impl<'a> From<&'a Props> for BootstrapProps<'a> {
|
||||
fn from(props: &Props) -> BootstrapProps {
|
||||
let class = &props.class;
|
||||
let borders = collect_bs(&props.border, &props.borders);
|
||||
let margins = collect_bs(&props.margin, &props.margins);
|
||||
let paddings = collect_bs(&props.padding, &props.paddings);
|
||||
BootstrapProps {
|
||||
class,
|
||||
borders,
|
||||
margins,
|
||||
paddings,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum Edge {
|
||||
All,
|
||||
Top,
|
||||
Right,
|
||||
Bottom,
|
||||
Left,
|
||||
LeftAndRight,
|
||||
TopAndBottom,
|
||||
}
|
||||
|
||||
impl Display for Edge {
|
||||
fn fmt(&self, fmt: &mut Formatter) -> Result {
|
||||
match self {
|
||||
Self::All => write!(fmt, ""),
|
||||
Self::Top => write!(fmt, "t"),
|
||||
Self::Bottom => write!(fmt, "b"),
|
||||
Self::Right => write!(fmt, "r"),
|
||||
Self::Left => write!(fmt, "l"),
|
||||
Self::LeftAndRight => write!(fmt, "x"),
|
||||
Self::TopAndBottom => write!(fmt, "y"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Edge {
|
||||
fn suffix(&self) -> &str {
|
||||
match self {
|
||||
Self::Top => "-top",
|
||||
_ => "",
|
||||
}
|
||||
}
|
||||
|
||||
fn with_prefix<S: AsRef<str>>(&self, prefix: S) -> String {
|
||||
match self {
|
||||
Self::All => prefix.as_ref().to_owned(),
|
||||
Self::LeftAndRight => format!(
|
||||
"{0}{1} {0}{2}",
|
||||
prefix.as_ref(),
|
||||
Self::Left.suffix(),
|
||||
Self::Right.suffix()
|
||||
),
|
||||
Self::TopAndBottom => format!(
|
||||
"{0}{1} {0}{2}",
|
||||
prefix.as_ref(),
|
||||
Self::Top.suffix(),
|
||||
Self::Bottom.suffix()
|
||||
),
|
||||
_ => format!("{}{}", prefix.as_ref(), self.suffix()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trait BootstrapClass {
|
||||
fn as_classname(&self) -> String;
|
||||
}
|
||||
|
||||
pub struct BootstrapProps<'a> {
|
||||
pub class: &'a str,
|
||||
pub borders: Vec<&'a Border>,
|
||||
pub margins: Vec<&'a Margin>,
|
||||
pub paddings: Vec<&'a Padding>,
|
||||
}
|
||||
|
||||
pub fn render_on_change<P: Properties + PartialEq>(
|
||||
props_on_comp: &mut P,
|
||||
props: P,
|
||||
|
@ -131,38 +26,3 @@ pub fn valid_as_class(v: &Option<bool>) -> &'static str {
|
|||
Some(false) => " is-invalid",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn collect_bs<'a, T>(t: &'a Option<T>, ts: &'a [T]) -> Vec<&'a T> {
|
||||
if let Some(t) = t.as_ref() {
|
||||
let mut r = vec![t];
|
||||
r.append(&mut ts.iter().collect());
|
||||
r
|
||||
} else {
|
||||
ts.iter().collect()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn calculate_classes<S: AsRef<str>>(prefix: S, props: BootstrapProps) -> String {
|
||||
let BootstrapProps {
|
||||
class,
|
||||
borders,
|
||||
margins,
|
||||
paddings,
|
||||
} = props;
|
||||
let mut classes = Vec::new();
|
||||
if !prefix.as_ref().is_empty() {
|
||||
classes.push(prefix.as_ref().to_owned());
|
||||
}
|
||||
if !props.class.is_empty() {
|
||||
classes.push(class.to_owned());
|
||||
}
|
||||
classes.append(&mut into_classnames(borders));
|
||||
classes.append(&mut into_classnames(margins));
|
||||
classes.append(&mut into_classnames(paddings));
|
||||
|
||||
classes.join(" ")
|
||||
}
|
||||
|
||||
fn into_classnames<C: BootstrapClass>(c: Vec<&C>) -> Vec<String> {
|
||||
c.into_iter().map(|c| c.as_classname()).collect()
|
||||
}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
use crate::props::IntoBsClass;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct Padding(pub super::Edge, pub usize);
|
||||
|
||||
impl super::BootstrapClass for Padding {
|
||||
impl IntoBsClass for Padding {
|
||||
fn as_classname(&self) -> String {
|
||||
format!("p{}-{}", self.0, self.1)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue