Standardize props

This commit is contained in:
Thomas Gideon 2020-06-03 15:33:25 -04:00
parent 96b6152d7b
commit c833bb1957
17 changed files with 358 additions and 252 deletions

19
examples/Cargo.toml Normal file
View file

@ -0,0 +1,19 @@
[package]
name = "examples"
version = "0.1.0"
authors = ["Thomas Gideon <cmdln@thecommandline.net>"]
edition = "2018"
[lib]
crate-type = ["cdylib", "rlib"]
[dependencies]
bootstrap-rs = { path = "../" }
yew = "~0.16.2"
log = "~0.4.8"
anyhow = "^1.0.28"
wasm-bindgen = "~0.2.61"
web-sys = "~0.3.38"
wasm-logger = "~0.2.0"
yew-router = "~0.13.0"
yew-components = "~0.1.2"

52
examples/src/lib.rs Normal file
View file

@ -0,0 +1,52 @@
use bootstrap_rs::{prelude::*, Breadcrumb, BreadcrumbItem, Container, Jumbotron};
use yew::{html::Children, prelude::*};
pub struct Example {
props: Props,
}
#[derive(Properties, Clone, PartialEq)]
pub struct Props {
#[prop_or_default]
pub children: Children,
}
impl Component for Example {
type Properties = Props;
type Message = ();
fn create(props: Self::Properties, _: ComponentLink<Self>) -> Self {
Self { props }
}
fn update(&mut self, _: Self::Message) -> ShouldRender {
false
}
fn change(&mut self, props: Self::Properties) -> ShouldRender {
render_on_change(&mut self.props, props)
}
fn view(&self) -> Html {
html! {
<Container>
<Jumbotron>
<h1>{ "Example!" }</h1>
</Jumbotron>
<Breadcrumb
margin=Margin(Edge::Bottom, 3)
>
<BreadcrumbItem active=false>
{ "Grandparent" }
</BreadcrumbItem>
<BreadcrumbItem active=false>
{ "Parent" }
</BreadcrumbItem>
<BreadcrumbItem active=true>
{ "Active" }
</BreadcrumbItem>
</Breadcrumb>
</Container>
}
}
}

View file

@ -9,6 +9,22 @@ pub struct BreadcrumbItem {
pub struct Props { pub struct Props {
pub active: bool, pub active: bool,
#[prop_or_default] #[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, pub children: Children,
} }
@ -31,16 +47,41 @@ impl Component for BreadcrumbItem {
fn view(&self) -> Html { fn view(&self) -> Html {
if self.props.active { if self.props.active {
html! { html! {
<li class="breadcrumb-item active" aria-current="page"> <li class=self.classes() aria-current="page">
{ self.props.children.render() } { self.props.children.render() }
</li> </li>
} }
} else { } else {
html! { html! {
<li class="breadcrumb-item"> <li class=self.classes()>
{ self.props.children.render() } { self.props.children.render() }
</li> </li>
} }
} }
} }
} }
impl BreadcrumbItem {
fn classes(&self) -> String {
if self.props.active {
calculate_classes("breadcrumb-item active", (&self.props).into())
} else {
calculate_classes("breadcrumb-item", (&self.props).into())
}
}
}
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,
}
}
}

View file

@ -2,34 +2,12 @@ mod item;
use crate::prelude::*; use crate::prelude::*;
pub use item::BreadcrumbItem; pub use item::BreadcrumbItem;
use yew::{html::Children, prelude::*}; use yew::prelude::*;
pub struct Breadcrumb { pub struct Breadcrumb {
props: Props, props: Props,
} }
#[derive(Properties, Clone, PartialEq)]
pub struct Props {
#[prop_or_default]
pub border: Option<Border>,
#[prop_or_default]
pub borders: Vec<Border>,
#[prop_or_default]
pub border_color: Option<BorderColor>,
#[prop_or_default]
pub border_colors: Vec<BorderColor>,
#[prop_or_default]
pub margin: Option<Margin>,
#[prop_or_default]
pub margins: Vec<Margin>,
#[prop_or_default]
pub class: String,
#[prop_or_default]
pub style: String,
#[prop_or_default]
pub children: Children,
}
impl Component for Breadcrumb { impl Component for Breadcrumb {
type Properties = Props; type Properties = Props;
type Message = (); type Message = ();
@ -47,9 +25,10 @@ impl Component for Breadcrumb {
} }
fn view(&self) -> Html { fn view(&self) -> Html {
let class = calculate_classes("breadcrumb", (&self.props).into());
html! { html! {
<nav <nav
class=self.props.class.clone() class=class
aria-label="breadcrumb" aria-label="breadcrumb"
style=self.props.style.clone() style=self.props.style.clone()
> >
@ -62,16 +41,3 @@ impl Component for Breadcrumb {
} }
} }
} }
impl<'a> From<&'a Props> for BootstrapProps<'a> {
fn from(props: &Props) -> BootstrapProps {
let borders = collect_bs(&props.border, &props.borders);
let border_colors = collect_bs(&props.border_color, &props.border_colors);
let margins = collect_bs(&props.margin, &props.margins);
BootstrapProps {
borders,
border_colors,
margins,
}
}
}

View file

@ -1,24 +1,10 @@
use crate::prelude::*; use crate::prelude::*;
use yew::{html::Children, prelude::*}; use yew::prelude::*;
pub struct ButtonGroup { pub struct ButtonGroup {
props: Props, props: Props,
} }
#[derive(Properties, Clone, PartialEq)]
pub struct Props {
#[prop_or_default]
pub class: String,
#[prop_or_default]
pub style: String,
#[prop_or_default]
pub role: String,
#[prop_or_default]
pub aria_label: String,
#[prop_or_default]
pub children: Children,
}
impl Component for ButtonGroup { impl Component for ButtonGroup {
type Properties = Props; type Properties = Props;
type Message = (); type Message = ();
@ -38,7 +24,7 @@ impl Component for ButtonGroup {
fn view(&self) -> Html { fn view(&self) -> Html {
html! { html! {
<div class=self.class() <div class=self.class()
style=self.style() style=self.props.style.clone()
role=self.props.role.clone() role=self.props.role.clone()
aria-label=self.props.aria_label.clone() aria-label=self.props.aria_label.clone()
> >
@ -56,12 +42,4 @@ impl ButtonGroup {
format!("btn-group {}", self.props.class) format!("btn-group {}", self.props.class)
} }
} }
fn style(&self) -> &str {
if self.props.style.is_empty() {
""
} else {
&self.props.style
}
}
} }

View file

@ -1,20 +1,10 @@
use crate::prelude::*; use crate::prelude::*;
use yew::{html::Children, prelude::*}; use yew::prelude::*;
pub struct CardBody { pub struct CardBody {
props: Props, props: Props,
} }
#[derive(Properties, Clone, PartialEq)]
pub struct Props {
#[prop_or_default]
pub class: String,
#[prop_or_default]
pub style: String,
#[prop_or_default]
pub children: Children,
}
impl Component for CardBody { impl Component for CardBody {
type Properties = Props; type Properties = Props;
type Message = (); type Message = ();
@ -32,28 +22,11 @@ impl Component for CardBody {
} }
fn view(&self) -> Html { fn view(&self) -> Html {
let class = calculate_classes("card-body", (&self.props).into());
html! { html! {
<div class=self.class() style=self.style()> <div class=class style=self.props.style.clone()>
{ self.props.children.render() } { self.props.children.render() }
</div> </div>
} }
} }
} }
impl CardBody {
fn class(&self) -> String {
if self.props.class.is_empty() {
"card-body".into()
} else {
format!("card-body {}", self.props.class)
}
}
fn style(&self) -> &str {
if self.props.style.is_empty() {
""
} else {
&self.props.style
}
}
}

View file

@ -4,34 +4,12 @@ mod text;
pub use self::{body::CardBody, header::CardHeader, text::CardText}; pub use self::{body::CardBody, header::CardHeader, text::CardText};
use crate::prelude::*; use crate::prelude::*;
use yew::{html::Children, prelude::*}; use yew::prelude::*;
pub struct Card { pub struct Card {
props: Props, props: Props,
} }
#[derive(Properties, Clone, PartialEq)]
pub struct Props {
#[prop_or_default]
pub margin: Option<Margin>,
#[prop_or_default]
pub margins: Vec<Margin>,
#[prop_or_default]
pub border: Option<Border>,
#[prop_or_default]
pub borders: Vec<Border>,
#[prop_or_default]
pub border_color: Option<BorderColor>,
#[prop_or_default]
pub border_colors: Vec<BorderColor>,
#[prop_or_default]
pub class: String,
#[prop_or_default]
pub style: String,
#[prop_or_default]
pub children: Children,
}
impl Component for Card { impl Component for Card {
type Properties = Props; type Properties = Props;
type Message = (); type Message = ();
@ -49,45 +27,11 @@ impl Component for Card {
} }
fn view(&self) -> Html { fn view(&self) -> Html {
let class = calculate_classes("card", (&self.props).into());
html! { html! {
<div class=self.class() style=self.style()> <div class=class style=self.props.style.clone()>
{ self.props.children.render() } { self.props.children.render() }
</div> </div>
} }
} }
} }
impl Card {
fn class(&self) -> String {
if self.props.class.is_empty() {
format!("card {}", calculate_classes((&self.props).into()))
} else {
format!(
"card {} {}",
self.props.class,
calculate_classes((&self.props).into())
)
}
}
fn style(&self) -> &str {
if self.props.style.is_empty() {
""
} else {
&self.props.style
}
}
}
impl<'a> From<&'a Props> for BootstrapProps<'a> {
fn from(props: &'a Props) -> Self {
let borders = collect_bs(&props.border, &props.borders);
let border_colors = collect_bs(&props.border_color, &props.border_colors);
let margins = collect_bs(&props.margin, &props.margins);
Self {
borders,
border_colors,
margins,
}
}
}

View file

@ -1,16 +1,10 @@
use crate::prelude::*; use crate::prelude::*;
use yew::{html::Children, prelude::*}; use yew::prelude::*;
pub struct Container { pub struct Container {
props: Props, props: Props,
} }
#[derive(Properties, Clone, PartialEq)]
pub struct Props {
#[prop_or_default]
pub children: Children,
}
impl Component for Container { impl Component for Container {
type Properties = Props; type Properties = Props;
type Message = (); type Message = ();
@ -29,9 +23,31 @@ impl Component for Container {
fn view(&self) -> Html { fn view(&self) -> Html {
html! { html! {
<div class="container"> <div class=calculate_classes("container", (&self.props).into())>
{ self.props.children.render() } { self.props.children.render() }
</div> </div>
} }
} }
} }
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test() {
let container = Container {
props: Props {
margin: Some(Margin(Edge::All, 3)),
padding: Some(Padding(Edge::Top, 3)),
..Props::default()
},
};
let expected = html! {
<div class="container m-3 pt-3">
<></>
</div>
};
assert_eq!(expected, container.view());
}
}

View file

@ -1,35 +1,10 @@
use crate::prelude::*; use crate::prelude::*;
use yew::{html::Children, prelude::*}; use yew::prelude::*;
pub struct InputGroup { pub struct InputGroup {
props: Props, props: Props,
} }
#[derive(Properties, Clone, PartialEq)]
pub struct Props {
#[prop_or_default]
pub margin: Option<Margin>,
#[prop_or_default]
pub margins: Vec<Margin>,
#[prop_or_default]
pub class: String,
#[prop_or_default]
pub children: Children,
}
impl<'a> From<&'a Props> for BootstrapProps<'a> {
fn from(props: &'a Props) -> BootstrapProps<'a> {
let borders = Vec::new();
let border_colors = Vec::new();
let margins = collect_bs(&props.margin, &props.margins);
Self {
borders,
border_colors,
margins,
}
}
}
impl Component for InputGroup { impl Component for InputGroup {
type Message = (); type Message = ();
type Properties = Props; type Properties = Props;
@ -47,9 +22,9 @@ impl Component for InputGroup {
} }
fn view(&self) -> Html { fn view(&self) -> Html {
let classes = calculate_classes((&self.props).into()); let class = calculate_classes("input-group", (&self.props).into());
html! { html! {
<div class=format!("input-group {} {}", classes, self.props.class)> <div class=class>
{ self.props.children.render() } { self.props.children.render() }
</div> </div>
} }

View file

@ -33,12 +33,28 @@ pub struct Props {
pub name: String, pub name: String,
#[prop_or_default] #[prop_or_default]
pub id: String, pub id: String,
pub on_signal: Callback<String>, pub on_change: Callback<String>,
pub input_type: InputType, pub input_type: InputType,
#[prop_or_default] #[prop_or_default]
pub readonly: bool, pub readonly: bool,
#[prop_or_default] #[prop_or_default]
pub value: String, pub value: 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,
} }
impl Component for Input { impl Component for Input {
@ -53,7 +69,7 @@ impl Component for Input {
fn update(&mut self, msg: Self::Message) -> ShouldRender { fn update(&mut self, msg: Self::Message) -> ShouldRender {
if let InputChange(ChangeData::Value(value)) = msg { if let InputChange(ChangeData::Value(value)) = msg {
self.state = value.clone(); self.state = value.clone();
self.props.on_signal.emit(value); self.props.on_change.emit(value);
true true
} else { } else {
false false
@ -69,9 +85,9 @@ impl Component for Input {
fn view(&self) -> Html { fn view(&self) -> Html {
let class = if self.props.readonly { let class = if self.props.readonly {
"form-control-plaintext pl-3" calculate_classes("form-control-plaintext", (&self.props).into())
} else { } else {
"form-control" calculate_classes("form-control", (&self.props).into())
}; };
html! { html! {
<input <input
@ -86,3 +102,18 @@ impl Component for Input {
} }
} }
} }
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,
}
}
}

View file

@ -16,7 +16,23 @@ pub struct Props {
pub name: String, pub name: String,
#[prop_or_default] #[prop_or_default]
pub id: String, pub id: String,
pub on_signal: Callback<String>, pub on_change: Callback<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,
} }
impl Component for TextArea { impl Component for TextArea {
@ -31,7 +47,7 @@ impl Component for TextArea {
fn update(&mut self, msg: Self::Message) -> ShouldRender { fn update(&mut self, msg: Self::Message) -> ShouldRender {
if let InputChange(ChangeData::Value(value)) = msg { if let InputChange(ChangeData::Value(value)) = msg {
self.state = value.clone(); self.state = value.clone();
self.props.on_signal.emit(value); self.props.on_change.emit(value);
true true
} else { } else {
false false
@ -47,7 +63,7 @@ impl Component for TextArea {
<textarea <textarea
name=&self.props.name name=&self.props.name
id=&self.props.id id=&self.props.id
class="form-control" class=calculate_classes("form-control", (&self.props).into())
onchange=self.link.callback(|evt| InputChange(evt)) onchange=self.link.callback(|evt| InputChange(evt))
> >
{ &self.state } { &self.state }
@ -55,3 +71,18 @@ impl Component for TextArea {
} }
} }
} }
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,
}
}
}

View file

@ -1,22 +1,10 @@
use crate::prelude::*; use crate::prelude::*;
use yew::{html::Children, prelude::*}; use yew::prelude::*;
pub struct Jumbotron { pub struct Jumbotron {
props: Props, props: Props,
} }
#[derive(Properties, Clone)]
pub struct Props {
#[prop_or_default]
pub margin: Option<Margin>,
#[prop_or_default]
pub margins: Vec<Margin>,
#[prop_or_default]
pub class: String,
#[prop_or_default]
pub children: Children,
}
impl Component for Jumbotron { impl Component for Jumbotron {
type Properties = Props; type Properties = Props;
type Message = (); type Message = ();
@ -34,8 +22,9 @@ impl Component for Jumbotron {
} }
fn view(&self) -> Html { fn view(&self) -> Html {
let class = calculate_classes("jumbotron", (&self.props).into());
html! { html! {
<div class=format!("jumbotron {}", self.props.class)> <div class=class>
{ self.props.children.render() } { self.props.children.render() }
</div> </div>
} }

View file

@ -1,20 +1,13 @@
use super::{Color, Edge};
#[derive(Clone, PartialEq)] #[derive(Clone, PartialEq)]
pub enum Border { pub struct Border(pub Edge, pub Color);
All,
Top,
Right,
Bottom,
Left,
}
impl super::BootstrapClass for Border { impl super::BootstrapClass for Border {
fn as_classname(&self) -> String { fn as_classname(&self) -> String {
match self { let edge = match self.0 {
Self::All => "border".into(), Edge::All => "border".to_owned(),
Self::Top => "border-top".into(), _ => self.0.with_prefix("border"),
Self::Right => "border-right".into(), };
Self::Bottom => "border-bottom".into(), format!("{} {}", edge, self.1.with_prefix("border"))
Self::Left => "border-left".into(),
}
} }
} }

View file

@ -1,22 +0,0 @@
#[derive(Clone, PartialEq)]
pub enum BorderColor {
Primary,
Secondary,
Unset,
}
impl Default for BorderColor {
fn default() -> Self {
BorderColor::Unset
}
}
impl super::BootstrapClass for BorderColor {
fn as_classname(&self) -> String {
match self {
Self::Primary => "border-primary".into(),
Self::Secondary => "border-secondary".into(),
Self::Unset => "".into(),
}
}
}

36
src/prelude/color.rs Normal file
View file

@ -0,0 +1,36 @@
#[derive(Clone, PartialEq)]
pub enum Color {
Primary,
Secondary,
Success,
Danger,
Warning,
Info,
Light,
Dark,
White,
Unset,
}
impl Default for Color {
fn default() -> Self {
Self::Unset
}
}
impl Color {
pub fn with_prefix<S: AsRef<str>>(&self, prefix: S) -> String {
match self {
Self::Primary => format!("{}-primary", prefix.as_ref()),
Self::Secondary => format!("{}-secondary", prefix.as_ref()),
Self::Success => format!("{}-success", prefix.as_ref()),
Self::Danger => format!("{}-danger", prefix.as_ref()),
Self::Warning => format!("{}-warning", prefix.as_ref()),
Self::Info => format!("{}-info", prefix.as_ref()),
Self::Light => format!("{}-light", prefix.as_ref()),
Self::Dark => format!("{}-dark", prefix.as_ref()),
Self::White => format!("{}-white", prefix.as_ref()),
Self::Unset => "".into(),
}
}
}

View file

@ -1,26 +1,102 @@
mod border; mod border;
mod border_color; mod color;
mod margin; mod margin;
mod padding;
pub use self::{border::Border, border_color::BorderColor, margin::Margin}; pub use self::{border::Border, color::Color, margin::Margin, padding::Padding};
use std::fmt::{Display, Formatter, Result}; use std::fmt::{Display, Formatter, Result};
use yew::prelude::*; 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)] #[derive(Debug, Clone, PartialEq)]
pub enum Edge { pub enum Edge {
All,
Top, Top,
Right, Right,
Bottom, Bottom,
Left, Left,
LeftAndRight,
TopAndBottom,
} }
impl Display for Edge { impl Display for Edge {
fn fmt(&self, fmt: &mut Formatter) -> Result { fn fmt(&self, fmt: &mut Formatter) -> Result {
match self { match self {
Self::All => write!(fmt, ""),
Self::Top => write!(fmt, "t"), Self::Top => write!(fmt, "t"),
Self::Bottom => write!(fmt, "b"), Self::Bottom => write!(fmt, "b"),
Self::Right => write!(fmt, "r"), Self::Right => write!(fmt, "r"),
Self::Left => write!(fmt, "l"), 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()),
} }
} }
} }
@ -30,9 +106,10 @@ trait BootstrapClass {
} }
pub struct BootstrapProps<'a> { pub struct BootstrapProps<'a> {
pub class: &'a str,
pub borders: Vec<&'a Border>, pub borders: Vec<&'a Border>,
pub border_colors: Vec<&'a BorderColor>,
pub margins: Vec<&'a Margin>, pub margins: Vec<&'a Margin>,
pub paddings: Vec<&'a Padding>,
} }
pub fn render_on_change<P: Properties + PartialEq>( pub fn render_on_change<P: Properties + PartialEq>(
@ -57,16 +134,23 @@ pub fn collect_bs<'a, T>(t: &'a Option<T>, ts: &'a [T]) -> Vec<&'a T> {
} }
} }
pub fn calculate_classes(props: BootstrapProps) -> String { pub fn calculate_classes<S: AsRef<str>>(prefix: S, props: BootstrapProps) -> String {
let BootstrapProps { let BootstrapProps {
class,
borders, borders,
border_colors,
margins, margins,
paddings,
} = props; } = props;
let mut classes = Vec::new(); 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(borders));
classes.append(&mut into_classnames(border_colors));
classes.append(&mut into_classnames(margins)); classes.append(&mut into_classnames(margins));
classes.append(&mut into_classnames(paddings));
classes.join(" ") classes.join(" ")
} }

View file

@ -3,6 +3,6 @@ pub struct Padding(pub super::Edge, pub usize);
impl super::BootstrapClass for Padding { impl super::BootstrapClass for Padding {
fn as_classname(&self) -> String { fn as_classname(&self) -> String {
format!("m{}-{}", self.0, self.1) format!("p{}-{}", self.0, self.1)
} }
} }