diff --git a/README.md b/README.md index ec29edd..b851fbe 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Bug reports, feature requests, and pull requests are welcome! Please try to match your code style to the existing codebase. If you think a change in that style is warranted, feel free to make a suggestion in a new Issue. -Much of this codebase uses struct components. **For new contributions please use functional components** unless you have good reason to use struct components. It is the [recommended default from Yew](https://yew.rs/docs/concepts/function-components)[^1], and we should be consistent. +**For new contributions please use functional components** unless you have good reason to use struct components. It is the [recommended default from Yew](https://yew.rs/docs/concepts/function-components)[^1], and we should be consistent. [^1]: > function components - the recommended way to write components when starting with Yew and when writing simple presentation logic. Please be sure to try `cargo test` before submitting a PR. diff --git a/examples/Cargo.lock b/examples/Cargo.lock index 4896b08..b67d0e8 100644 --- a/examples/Cargo.lock +++ b/examples/Cargo.lock @@ -1147,7 +1147,7 @@ dependencies = [ [[package]] name = "yew-bootstrap" -version = "0.6.3" +version = "0.7.0" dependencies = [ "anyhow", "convert_case", diff --git a/packages/yew-bootstrap/src/component/accordion.rs b/packages/yew-bootstrap/src/component/accordion.rs index ddb19a6..fb740c1 100644 --- a/packages/yew-bootstrap/src/component/accordion.rs +++ b/packages/yew-bootstrap/src/component/accordion.rs @@ -245,8 +245,8 @@ pub struct AccordionProps { /// { /// items.iter().map(|item| { /// html_nested! { -/// -/// {item.0.clone()} +/// +/// {item.0} /// /// } /// }).collect::>>() diff --git a/packages/yew-bootstrap/src/component/alert.rs b/packages/yew-bootstrap/src/component/alert.rs index 9d665b7..5ef1972 100644 --- a/packages/yew-bootstrap/src/component/alert.rs +++ b/packages/yew-bootstrap/src/component/alert.rs @@ -2,25 +2,6 @@ use yew::prelude::*; use crate::util::Color; -/// # Alert component -/// Used alongside [crate::util::Color] to create Alert components -/// -/// See [AlertProps] for a listing of properties -/// -/// ## Example -/// ```rust -/// use yew::prelude::*; -/// use yew_bootstrap::component::Alert; -/// use yew_bootstrap::util::Color; -/// fn test() -> Html { -/// html!{ -/// -/// {"This is a primary alert!"} -/// -/// } -/// } -/// ``` -pub struct Alert {} /// # Properties of [Alert] #[derive(Properties, Clone, PartialEq)] @@ -42,29 +23,38 @@ pub struct AlertProps { pub text: String, } -impl Component for Alert { - type Message = (); - type Properties = AlertProps; - - fn create(_ctx: &Context) -> Self { - Self {} - } - - fn view(&self, ctx: &Context) -> Html { - let props = ctx.props(); - let mut classes = Classes::new(); - classes.push("alert"); - classes.push(format!("alert-{}", props.style)); - classes.push(props.class.clone()); - - html! { - - } +/// # Alert component +/// Used alongside [crate::util::Color] to create Alert components +/// +/// See [AlertProps] for a listing of properties +/// +/// ## Example +/// ```rust +/// use yew::prelude::*; +/// use yew_bootstrap::component::Alert; +/// use yew_bootstrap::util::Color; +/// fn test() -> Html { +/// html!{ +/// +/// {"This is a primary alert!"} +/// +/// } +/// } +/// ``` +#[function_component] +pub fn Alert(props: &AlertProps) -> Html { + let mut classes = Classes::new(); + classes.push("alert"); + classes.push(format!("alert-{}", props.style)); + classes.push(props.class.clone()); + + html! { + } } diff --git a/packages/yew-bootstrap/src/component/badge.rs b/packages/yew-bootstrap/src/component/badge.rs index 1979c08..632ad09 100644 --- a/packages/yew-bootstrap/src/component/badge.rs +++ b/packages/yew-bootstrap/src/component/badge.rs @@ -2,26 +2,6 @@ use yew::prelude::*; use crate::util::{Color, ArrangeX, ArrangeY}; -/// # Badge component -/// Used alongside [crate::util::Color] to create Badge components -/// -/// See [BadgeProps] for a listing of properties -/// -/// ## Example -/// ```rust -/// use yew::prelude::*; -/// use yew_bootstrap::component::Badge; -/// use yew_bootstrap::util::Color; -/// fn test() -> Html { -/// html!{ -/// -/// {"This is a primary badge!"} -/// -/// } -/// } -/// ``` -pub struct Badge {} - /// # Properties of [Badge] #[derive(Properties, Clone, PartialEq)] pub struct BadgeProps { @@ -50,43 +30,52 @@ pub struct BadgeProps { pub text: String, } -impl Component for Badge { - type Message = (); - type Properties = BadgeProps; - - fn create(_ctx: &Context) -> Self { - Self {} - } - - fn view(&self, ctx: &Context) -> Html { - let props = ctx.props(); - let mut classes = Classes::new(); - match &props.position { - Some(position) => { - classes.push("position-absolute".to_string()); - classes.push(format!("{}", position.0)); - classes.push(format!("{}", position.1)); - classes.push("translate-middle".to_string()); - } - None => {} - } - classes.push("badge"); - if props.pill { - classes.push("rounded-pill"); - } - classes.push(format!("bg-{}", props.style)); - if [Color::Warning, Color::Info, Color::Light].contains(&props.style) { - classes.push("text-dark"); +/// # Badge component +/// Used alongside [crate::util::Color] to create Badge components +/// +/// See [BadgeProps] for a listing of properties +/// +/// ## Example +/// ```rust +/// use yew::prelude::*; +/// use yew_bootstrap::component::Badge; +/// use yew_bootstrap::util::Color; +/// fn test() -> Html { +/// html!{ +/// +/// {"This is a primary badge!"} +/// +/// } +/// } +/// ``` +#[function_component] +pub fn Badge(props: &BadgeProps) -> Html { + let mut classes = Classes::new(); + match &props.position { + Some(position) => { + classes.push("position-absolute".to_string()); + classes.push(format!("{}", position.0)); + classes.push(format!("{}", position.1)); + classes.push("translate-middle".to_string()); } - classes.push(props.class.clone()); + None => {} + } + classes.push("badge"); + if props.pill { + classes.push("rounded-pill"); + } + classes.push(format!("bg-{}", props.style)); + if [Color::Warning, Color::Info, Color::Light].contains(&props.style) { + classes.push("text-dark"); + } + classes.push(props.class.clone()); - html! { - - { &props.text } - { for props.children.iter() } - - } + html! { + + { &props.text } + { for props.children.iter() } + } } diff --git a/packages/yew-bootstrap/src/component/button.rs b/packages/yew-bootstrap/src/component/button.rs index 4c83240..4d6f31c 100644 --- a/packages/yew-bootstrap/src/component/button.rs +++ b/packages/yew-bootstrap/src/component/button.rs @@ -14,51 +14,6 @@ impl Default for ButtonSize { } } -/// # Button component -/// Button with various properties, including support for opening or closing a modal -/// dialog [crate::component::Modal]. -/// -/// Buttons can be grouped in a [crate::component::ButtonGroup]. -/// -/// See [ButtonProps] for a listing of properties. -/// -/// ## Example -/// Example of a simple button: -/// -/// ```rust -/// use yew::prelude::*; -/// use yew_bootstrap::component::Button; -/// use yew_bootstrap::util::Color; -/// fn test() -> Html { -/// html!{ -/// -/// -/// -/// -/// } -/// } -/// ``` -pub struct Button {} - /// # Properties for [Button] #[derive(Properties, Clone, PartialEq)] pub struct ButtonProps { @@ -111,66 +66,99 @@ pub struct ButtonProps { pub modal_dismiss: bool, } -impl Component for Button { - type Message = (); - type Properties = ButtonProps; - - fn create(_ctx: &Context) -> Self { - Self {} +/// # Button component +/// Button with various properties, including support for opening or closing a modal +/// dialog [crate::component::Modal]. +/// +/// Buttons can be grouped in a [crate::component::ButtonGroup]. +/// +/// See [ButtonProps] for a listing of properties. +/// +/// ## Example +/// Example of a simple button: +/// +/// ```rust +/// use yew::prelude::*; +/// use yew_bootstrap::component::Button; +/// use yew_bootstrap::util::Color; +/// fn test() -> Html { +/// html!{ +/// +/// +/// +/// +/// } +/// } +/// ``` +#[function_component] +pub fn Button(props: &ButtonProps) -> Html { + let mut classes = Classes::new(); + classes.push("btn"); + if props.outline { + classes.push(format!("btn-outline-{}", props.style)); + } else { + classes.push(format!("btn-{}", props.style)); } - - fn view(&self, ctx: &Context) -> Html { - let props = ctx.props(); - let mut classes = Classes::new(); - classes.push("btn"); - if props.outline { - classes.push(format!("btn-outline-{}", props.style)); - } else { - classes.push(format!("btn-{}", props.style)); - } - match props.size { - ButtonSize::Large => classes.push("btn-lg"), - ButtonSize::Small => classes.push("btn-sm"), - _ => (), - } - if props.block { - classes.push("btn-block"); + match props.size { + ButtonSize::Large => classes.push("btn-lg"), + ButtonSize::Small => classes.push("btn-sm"), + _ => (), + } + if props.block { + classes.push("btn-block"); + } + classes.push(props.class.clone()); + + let modal_dismiss = match props.modal_dismiss { + true => "modal", + false => "", + }; + + if let Some(target) = &props.modal_target { + html! { + } - classes.push(props.class.clone()); - - let modal_dismiss = match props.modal_dismiss { - true => "modal", - false => "", - }; - - if let Some(target) = &props.modal_target { - html! { - - } - } else { - html! { - - } + } else { + html! { + } - } } diff --git a/packages/yew-bootstrap/src/component/button_group.rs b/packages/yew-bootstrap/src/component/button_group.rs index a717545..21568d5 100644 --- a/packages/yew-bootstrap/src/component/button_group.rs +++ b/packages/yew-bootstrap/src/component/button_group.rs @@ -1,28 +1,5 @@ use yew::prelude::*; -/// # Button group -/// [ButtonGroup] is used to group several [crate::component::Button] instances together. -/// Buttons can be arranged vertically. -/// -/// See [ButtonGroupProps] for a listing of properties. -/// -/// ## Example -/// Example of a simple button group: -/// -/// ```rust -/// use yew::prelude::*; -/// use yew_bootstrap::component::{Button, ButtonGroup}; -/// use yew_bootstrap::util::Color; -/// fn test() -> Html { -/// html!{ -/// -/// -/// -/// -/// -/// } -/// } -/// ``` -pub struct Modal { } - -/// # Header for a [Modal] dialog -/// See [ModalHeaderProps] for a listing of properties -pub struct ModalHeader { } - -/// # Body for a [Modal] dialog -/// See [ModalBodyProps] for a listing of properties -pub struct ModalBody { } - -/// # Footer for a [Modal] dialog -/// See [ModalFooterProps] for a listing of properties -pub struct ModalFooter { } - /// Properties for [ModalFooter] #[derive(Properties, Clone, PartialEq)] pub struct ModalFooterProps { @@ -61,22 +22,14 @@ pub struct ModalFooterProps { pub children: Children } -impl Component for ModalFooter { - type Message = (); - type Properties = ModalFooterProps; - - fn create(_ctx: &Context) -> Self { - Self {} - } - - fn view(&self, ctx: &Context) -> Html { - let props = ctx.props(); - - html! { - - } +/// # Footer for a [Modal] dialog +/// See [ModalFooterProps] for a listing of properties +#[function_component] +pub fn ModalFooter(props: &ModalFooterProps) -> Html { + html! { + } } @@ -92,23 +45,16 @@ pub struct ModalHeaderProps { pub id: String, } -impl Component for ModalHeader { - type Message = (); - type Properties = ModalHeaderProps; - - fn create(_ctx: &Context) -> Self { - Self {} - } - - fn view(&self, ctx: &Context) -> Html { - let props = ctx.props(); - - html! { - - } +/// # Header for a [Modal] dialog +/// See [ModalHeaderProps] for a listing of properties +/// +#[function_component] +pub fn ModalHeader(props: &ModalHeaderProps) -> Html { + html! { + } } @@ -119,22 +65,15 @@ pub struct ModalBodyProps { pub children: Children } -impl Component for ModalBody { - type Message = (); - type Properties = ModalBodyProps; - - fn create(_ctx: &Context) -> Self { - Self {} - } - - fn view(&self, ctx: &Context) -> Html { - let props = ctx.props(); - html! { - - } +/// # Body for a [Modal] dialog +/// See [ModalBodyProps] for a listing of properties +#[function_component] +pub fn ModalBody(props: &ModalBodyProps) -> Html { + html! { + } } @@ -154,35 +93,50 @@ pub struct ModalProps { pub size: ModalSize, } -impl Component for Modal { - type Message = (); - type Properties = ModalProps; - - fn create(_ctx: &Context) -> Self { - Self {} +/// # Modal dialog +/// Modal dialog, parent of [ModalHeader], [ModalBody] and [ModalFooter]. +/// +/// See [ModalProps] for a listing of properties +/// +/// ## Example +/// ```rust +/// use yew::prelude::*; +/// use yew_bootstrap::component::{Modal, ModalHeader, ModalBody, ModalFooter, Button, ModalSize}; +/// use yew_bootstrap::util::Color; +/// fn test() -> Html { +/// html!{ +/// // size defaults to Normal +/// +/// +///

{"Modal body text goes here."}

+///
+/// +/// +/// +/// +///
+/// } +/// } +/// ``` +#[function_component] +pub fn Modal(props: &ModalProps) -> Html { + let mut dialog_classes = Classes::new(); + dialog_classes.push("modal-dialog"); + + match props.size { + ModalSize::ExtraLarge => dialog_classes.push("modal-xl"), + ModalSize::Large => dialog_classes.push("modal-lg"), + ModalSize::Small => dialog_classes.push("modal-sm"), + _ => (), } - fn view(&self, ctx: &Context) -> Html { - let props = ctx.props(); - - let mut dialog_classes = Classes::new(); - dialog_classes.push("modal-dialog"); - - match props.size { - ModalSize::ExtraLarge => dialog_classes.push("modal-xl"), - ModalSize::Large => dialog_classes.push("modal-lg"), - ModalSize::Small => dialog_classes.push("modal-sm"), - _ => (), - } - - html! { -