yew_and_bulma/layout/
level.rs

1use yew::html;
2use yew::{
3    function_component, html::ChildrenRenderer, virtual_dom::VChild, Children, ChildrenWithProps,
4    Html, Properties,
5};
6use yew_and_bulma_macros::base_component_properties;
7
8use crate::utils::class::ClassBuilder;
9
10/// Defines the properties of the [Bulma level element][bd].
11///
12/// Defines the properties of the level element, based on the specification
13/// found in the [Bulma level element documentation][bd].
14///
15/// # Examples
16///
17/// ```rust
18/// use yew::prelude::*;
19/// use yew_and_bulma::layout::level::{Level, LevelItem};
20///
21/// #[function_component(App)]
22/// fn app() -> Html {
23///     html! {
24///         <Level>
25///             <LevelItem>{"This is some text in a level."}</LevelItem>
26///         </Level>
27///     }
28/// }
29/// ```
30///
31/// [bd]: https://bulma.io/documentation/layout/level/
32#[base_component_properties]
33#[derive(Properties, PartialEq)]
34pub struct LevelProperties {
35    /// Whether or not the [level element][bd] should be horizontal on mobile.
36    ///
37    /// Whether or not the [Bulma level element][bd], which will receive
38    /// these properties, should be horizontal on mobile devices.
39    ///
40    /// # Examples
41    ///
42    /// ```rust
43    /// use yew::prelude::*;
44    /// use yew_and_bulma::layout::level::{Level, LevelItem};
45    ///
46    /// #[function_component(App)]
47    /// fn app() -> Html {
48    ///     html! {
49    ///         <Level mobile={true}>
50    ///             <LevelItem>{"This is some text in a level."}</LevelItem>
51    ///         </Level>
52    ///     }
53    /// }
54    /// ```
55    ///
56    /// [bd]: https://bulma.io/documentation/layout/level/#mobile-level
57    #[prop_or_default]
58    pub mobile: bool,
59    /// The list of elements found inside the [level element][bd].
60    ///
61    /// Defines the elements that will be found inside the
62    /// [Bulma level element][bd] which will receive these properties.
63    ///
64    /// [bd]: https://bulma.io/documentation/layout/level/
65    pub children: ChildrenRenderer<LevelElement>,
66}
67
68/// Yew implementation of the [Bulma level element][bd].
69///
70/// Yew implementation of the level element, based on the specification
71/// found in the [Bulma level element documentation][bd].
72///
73/// # Examples
74///
75/// ```rust
76/// use yew::prelude::*;
77/// use yew_and_bulma::layout::level::{Level, LevelItem};
78///
79/// #[function_component(App)]
80/// fn app() -> Html {
81///     html! {
82///         <Level>
83///             <LevelItem>{"This is some text in a level."}</LevelItem>
84///         </Level>
85///     }
86/// }
87/// ```
88///
89/// [bd]: https://bulma.io/documentation/layout/level/
90#[function_component(Level)]
91pub fn level(props: &LevelProperties) -> Html {
92    let mobile = if props.mobile { "is-mobile" } else { "" };
93    let class = ClassBuilder::default()
94        .with_custom_class("level")
95        .with_custom_class(mobile)
96        .with_custom_class(
97            &props
98                .class
99                .as_ref()
100                .map(|c| c.to_string())
101                .unwrap_or("".to_owned()),
102        )
103        .build();
104
105    html! {
106        <div id={&props.id} {class}
107            onclick={props.onclick.clone()} onwheel={props.onwheel.clone()} onscroll={props.onscroll.clone()}
108            onmousedown={props.onmousedown.clone()} onmousemove={props.onmousemove.clone()} onmouseout={props.onmouseout.clone()} onmouseover={props.onmouseover.clone()} onmouseup={props.onmouseup.clone()}
109            ondrag={props.ondrag.clone()} ondragend={props.ondragend.clone()} ondragenter={props.ondragenter.clone()} ondragleave={props.ondragleave.clone()} ondragover={props.ondragover.clone()} ondragstart={props.ondragstart.clone()} ondrop={props.ondrop.clone()}
110            oncopy={props.oncopy.clone()} oncut={props.oncut.clone()} onpaste={props.onpaste.clone()}
111            onkeydown={props.onkeydown.clone()} onkeypress={props.onkeypress.clone()} onkeyup={props.onkeyup.clone()}
112            onblur={props.onblur.clone()} onchange={props.onchange.clone()} oncontextmenu={props.oncontextmenu.clone()} onfocus={props.onfocus.clone()} oninput={props.oninput.clone()} oninvalid={props.oninvalid.clone()} onreset={props.onreset.clone()} onselect={props.onselect.clone()} onsubmit={props.onsubmit.clone()}
113            onabort={props.onabort.clone()} oncanplay={props.oncanplay.clone()} oncanplaythrough={props.oncanplaythrough.clone()} oncuechange={props.oncuechange.clone()}
114            ondurationchange={props.ondurationchange.clone()} onemptied={props.onemptied.clone()} onended={props.onended.clone()} onerror={props.onerror.clone()}
115            onloadeddata={props.onloadeddata.clone()} onloadedmetadata={props.onloadedmetadata.clone()} onloadstart={props.onloadstart.clone()} onpause={props.onpause.clone()}
116            onplay={props.onplay.clone()} onplaying={props.onplaying.clone()} onprogress={props.onprogress.clone()} onratechange={props.onratechange.clone()}
117            onseeked={props.onseeked.clone()} onseeking={props.onseeking.clone()} onstalled={props.onstalled.clone()} onsuspend={props.onsuspend.clone()}
118            ontimeupdate={props.ontimeupdate.clone()} onvolumechange={props.onvolumechange.clone()} onwaiting={props.onwaiting.clone()}>
119            { for props.children.iter() }
120        </div>
121    }
122}
123
124/// Defines the possible types of children from a [Bulma level element][bd].
125///
126/// Defines the possible types of children found inside a
127/// [Bulma level element][bd].
128///
129/// # Examples
130///
131/// ```rust
132/// use yew::prelude::*;
133/// use yew_and_bulma::layout::level::{Level, LevelItem, LevelLeft, LevelRight};
134///
135/// #[function_component(App)]
136/// fn app() -> Html {
137///     html! {
138///         <Level>
139///             <LevelLeft>
140///                 <LevelItem>{ "Left aligned text in the level" }</LevelItem>
141///             </LevelLeft>
142///
143///             <LevelRight>
144///                 <LevelItem>{ "Right aligned text in the level" }</LevelItem>
145///             </LevelRight>
146///         </Level>
147///     }
148/// }
149/// ```
150///
151/// [bd]: https://bulma.io/documentation/layout/level/
152#[derive(Clone, PartialEq)]
153pub enum LevelElement {
154    LevelItem(VChild<LevelItem>),
155    LevelLeft(VChild<LevelLeft>),
156    LevelRight(VChild<LevelRight>),
157}
158
159impl From<VChild<LevelItem>> for LevelElement {
160    fn from(value: VChild<LevelItem>) -> Self {
161        LevelElement::LevelItem(value)
162    }
163}
164
165impl From<VChild<LevelLeft>> for LevelElement {
166    fn from(value: VChild<LevelLeft>) -> Self {
167        LevelElement::LevelLeft(value)
168    }
169}
170
171impl From<VChild<LevelRight>> for LevelElement {
172    fn from(value: VChild<LevelRight>) -> Self {
173        LevelElement::LevelRight(value)
174    }
175}
176
177#[allow(clippy::from_over_into)]
178impl Into<Html> for LevelElement {
179    fn into(self) -> Html {
180        match self {
181            LevelElement::LevelItem(li) => li.into(),
182            LevelElement::LevelLeft(ll) => ll.into(),
183            LevelElement::LevelRight(lr) => lr.into(),
184        }
185    }
186}
187
188/// Defines the properties of the [Bulma level item element][bd].
189///
190/// Defines the properties of the level item element, based on the specification
191/// found in the [Bulma level item element documentation][bd].
192///
193/// # Examples
194///
195/// ```rust
196/// use yew::prelude::*;
197/// use yew_and_bulma::layout::level::{Level, LevelItem};
198///
199/// #[function_component(App)]
200/// fn app() -> Html {
201///     html! {
202///         <Level>
203///             <LevelItem>{"This is some text in a level."}</LevelItem>
204///         </Level>
205///     }
206/// }
207/// ```
208///
209/// [bd]: https://bulma.io/documentation/layout/level/
210#[base_component_properties]
211#[derive(Properties, PartialEq)]
212pub struct LevelItemProperties {
213    /// The list of elements found inside the [level item element][bd].
214    ///
215    /// Defines the elements that will be found inside the
216    /// [Bulma level item element][bd] which will receive these properties.
217    ///
218    /// [bd]: https://bulma.io/documentation/layout/level/
219    pub children: Children,
220}
221
222/// Yew implementation of the [Bulma level item element][bd].
223///
224/// Yew implementation of the level item element, based on the specification
225/// found in the [Bulma level item element documentation][bd].
226///
227/// # Examples
228///
229/// ```rust
230/// use yew::prelude::*;
231/// use yew_and_bulma::layout::level::{Level, LevelItem};
232///
233/// #[function_component(App)]
234/// fn app() -> Html {
235///     html! {
236///         <Level>
237///             <LevelItem>{"This is some text in a level."}</LevelItem>
238///         </Level>
239///     }
240/// }
241/// ```
242///
243/// [bd]: https://bulma.io/documentation/layout/level/
244#[function_component(LevelItem)]
245pub fn level_item(props: &LevelItemProperties) -> Html {
246    let class = ClassBuilder::default()
247        .with_custom_class("level-item")
248        .with_custom_class(
249            &props
250                .class
251                .as_ref()
252                .map(|c| c.to_string())
253                .unwrap_or("".to_owned()),
254        )
255        .build();
256
257    html! {
258        <div id={&props.id} {class}
259            onclick={props.onclick.clone()} onwheel={props.onwheel.clone()} onscroll={props.onscroll.clone()}
260            onmousedown={props.onmousedown.clone()} onmousemove={props.onmousemove.clone()} onmouseout={props.onmouseout.clone()} onmouseover={props.onmouseover.clone()} onmouseup={props.onmouseup.clone()}
261            ondrag={props.ondrag.clone()} ondragend={props.ondragend.clone()} ondragenter={props.ondragenter.clone()} ondragleave={props.ondragleave.clone()} ondragover={props.ondragover.clone()} ondragstart={props.ondragstart.clone()} ondrop={props.ondrop.clone()}
262            oncopy={props.oncopy.clone()} oncut={props.oncut.clone()} onpaste={props.onpaste.clone()}
263            onkeydown={props.onkeydown.clone()} onkeypress={props.onkeypress.clone()} onkeyup={props.onkeyup.clone()}
264            onblur={props.onblur.clone()} onchange={props.onchange.clone()} oncontextmenu={props.oncontextmenu.clone()} onfocus={props.onfocus.clone()} oninput={props.oninput.clone()} oninvalid={props.oninvalid.clone()} onreset={props.onreset.clone()} onselect={props.onselect.clone()} onsubmit={props.onsubmit.clone()}
265            onabort={props.onabort.clone()} oncanplay={props.oncanplay.clone()} oncanplaythrough={props.oncanplaythrough.clone()} oncuechange={props.oncuechange.clone()}
266            ondurationchange={props.ondurationchange.clone()} onemptied={props.onemptied.clone()} onended={props.onended.clone()} onerror={props.onerror.clone()}
267            onloadeddata={props.onloadeddata.clone()} onloadedmetadata={props.onloadedmetadata.clone()} onloadstart={props.onloadstart.clone()} onpause={props.onpause.clone()}
268            onplay={props.onplay.clone()} onplaying={props.onplaying.clone()} onprogress={props.onprogress.clone()} onratechange={props.onratechange.clone()}
269            onseeked={props.onseeked.clone()} onseeking={props.onseeking.clone()} onstalled={props.onstalled.clone()} onsuspend={props.onsuspend.clone()}
270            ontimeupdate={props.ontimeupdate.clone()} onvolumechange={props.onvolumechange.clone()} onwaiting={props.onwaiting.clone()}>
271            { for props.children.iter() }
272        </div>
273    }
274}
275
276/// Defines the properties of the [Bulma level left element][bd].
277///
278/// Defines the properties of the level left element, based on the specification
279/// found in the [Bulma level left element documentation][bd].
280///
281/// # Examples
282///
283/// ```rust
284/// use yew::prelude::*;
285/// use yew_and_bulma::layout::level::{Level, LevelItem, LevelLeft};
286///
287/// #[function_component(App)]
288/// fn app() -> Html {
289///     html! {
290///         <Level>
291///             <LevelLeft>
292///                 <LevelItem>{"This is some text in a level left element."}</LevelItem>
293///             </LevelLeft>
294///         </Level>
295///     }
296/// }
297/// ```
298///
299/// [bd]: https://bulma.io/documentation/layout/level/
300#[base_component_properties]
301#[derive(Properties, PartialEq)]
302pub struct LevelLeftProperties {
303    /// The list of elements found inside the [level left element][bd].
304    ///
305    /// Defines the elements that will be found inside the
306    /// [Bulma level left element][bd] which will receive these properties.
307    ///
308    /// [bd]: https://bulma.io/documentation/layout/level/
309    pub children: ChildrenWithProps<LevelItem>,
310}
311
312/// Yew implementation of the [Bulma level left element][bd].
313///
314/// Yew implementation of the level left element, based on the specification
315/// found in the [Bulma level left element documentation][bd].
316///
317/// # Examples
318///
319/// ```rust
320/// use yew::prelude::*;
321/// use yew_and_bulma::layout::level::{Level, LevelItem, LevelLeft};
322///
323/// #[function_component(App)]
324/// fn app() -> Html {
325///     html! {
326///         <Level>
327///             <LevelLeft>
328///                 <LevelItem>{"This is some text in a level left element."}</LevelItem>
329///             </LevelLeft>
330///         </Level>
331///     }
332/// }
333/// ```
334///
335/// [bd]: https://bulma.io/documentation/layout/level/
336#[function_component(LevelLeft)]
337pub fn level_right(props: &LevelLeftProperties) -> Html {
338    let class = ClassBuilder::default()
339        .with_custom_class("level-left")
340        .with_custom_class(
341            &props
342                .class
343                .as_ref()
344                .map(|c| c.to_string())
345                .unwrap_or("".to_owned()),
346        )
347        .build();
348
349    html! {
350        <div id={&props.id} {class}
351            onclick={props.onclick.clone()} onwheel={props.onwheel.clone()} onscroll={props.onscroll.clone()}
352            onmousedown={props.onmousedown.clone()} onmousemove={props.onmousemove.clone()} onmouseout={props.onmouseout.clone()} onmouseover={props.onmouseover.clone()} onmouseup={props.onmouseup.clone()}
353            ondrag={props.ondrag.clone()} ondragend={props.ondragend.clone()} ondragenter={props.ondragenter.clone()} ondragleave={props.ondragleave.clone()} ondragover={props.ondragover.clone()} ondragstart={props.ondragstart.clone()} ondrop={props.ondrop.clone()}
354            oncopy={props.oncopy.clone()} oncut={props.oncut.clone()} onpaste={props.onpaste.clone()}
355            onkeydown={props.onkeydown.clone()} onkeypress={props.onkeypress.clone()} onkeyup={props.onkeyup.clone()}
356            onblur={props.onblur.clone()} onchange={props.onchange.clone()} oncontextmenu={props.oncontextmenu.clone()} onfocus={props.onfocus.clone()} oninput={props.oninput.clone()} oninvalid={props.oninvalid.clone()} onreset={props.onreset.clone()} onselect={props.onselect.clone()} onsubmit={props.onsubmit.clone()}
357            onabort={props.onabort.clone()} oncanplay={props.oncanplay.clone()} oncanplaythrough={props.oncanplaythrough.clone()} oncuechange={props.oncuechange.clone()}
358            ondurationchange={props.ondurationchange.clone()} onemptied={props.onemptied.clone()} onended={props.onended.clone()} onerror={props.onerror.clone()}
359            onloadeddata={props.onloadeddata.clone()} onloadedmetadata={props.onloadedmetadata.clone()} onloadstart={props.onloadstart.clone()} onpause={props.onpause.clone()}
360            onplay={props.onplay.clone()} onplaying={props.onplaying.clone()} onprogress={props.onprogress.clone()} onratechange={props.onratechange.clone()}
361            onseeked={props.onseeked.clone()} onseeking={props.onseeking.clone()} onstalled={props.onstalled.clone()} onsuspend={props.onsuspend.clone()}
362            ontimeupdate={props.ontimeupdate.clone()} onvolumechange={props.onvolumechange.clone()} onwaiting={props.onwaiting.clone()}>
363            { for props.children.iter() }
364        </div>
365    }
366}
367
368/// Defines the properties of the [Bulma level right element][bd].
369///
370/// Defines the properties of the level right element, based on the specification
371/// found in the [Bulma level right element documentation][bd].
372///
373/// # Examples
374///
375/// ```rust
376/// use yew::prelude::*;
377/// use yew_and_bulma::layout::level::{Level, LevelItem, LevelRight};
378///
379/// #[function_component(App)]
380/// fn app() -> Html {
381///     html! {
382///         <Level>
383///             <LevelRight>
384///                 <LevelItem>{"This is some text in a level right element."}</LevelItem>
385///             </LevelRight>
386///         </Level>
387///     }
388/// }
389/// ```
390///
391/// [bd]: https://bulma.io/documentation/layout/level/
392#[base_component_properties]
393#[derive(Properties, PartialEq)]
394pub struct LevelRightProperties {
395    /// The list of elements found inside the [level right element][bd].
396    ///
397    /// Defines the elements that will be found inside the
398    /// [Bulma level right element][bd] which will receive these properties.
399    ///
400    /// [bd]: https://bulma.io/documentation/layout/level/
401    pub children: ChildrenWithProps<LevelItem>,
402}
403
404/// Yew implementation of the [Bulma level right element][bd].
405///
406/// Yew implementation of the level right element, based on the specification
407/// found in the [Bulma level right element documentation][bd].
408///
409/// # Examples
410///
411/// ```rust
412/// use yew::prelude::*;
413/// use yew_and_bulma::layout::level::{Level, LevelItem, LevelRight};
414///
415/// #[function_component(App)]
416/// fn app() -> Html {
417///     html! {
418///         <Level>
419///             <LevelRight>
420///                 <LevelItem>{"This is some text in a level right element."}</LevelItem>
421///             </LevelRight>
422///         </Level>
423///     }
424/// }
425/// ```
426///
427/// [bd]: https://bulma.io/documentation/layout/level/
428#[function_component(LevelRight)]
429pub fn level_right(props: &LevelRightProperties) -> Html {
430    let class = ClassBuilder::default()
431        .with_custom_class("level-right")
432        .with_custom_class(
433            &props
434                .class
435                .as_ref()
436                .map(|c| c.to_string())
437                .unwrap_or("".to_owned()),
438        )
439        .build();
440
441    html! {
442        <div id={&props.id} {class}
443            onclick={props.onclick.clone()} onwheel={props.onwheel.clone()} onscroll={props.onscroll.clone()}
444            onmousedown={props.onmousedown.clone()} onmousemove={props.onmousemove.clone()} onmouseout={props.onmouseout.clone()} onmouseover={props.onmouseover.clone()} onmouseup={props.onmouseup.clone()}
445            ondrag={props.ondrag.clone()} ondragend={props.ondragend.clone()} ondragenter={props.ondragenter.clone()} ondragleave={props.ondragleave.clone()} ondragover={props.ondragover.clone()} ondragstart={props.ondragstart.clone()} ondrop={props.ondrop.clone()}
446            oncopy={props.oncopy.clone()} oncut={props.oncut.clone()} onpaste={props.onpaste.clone()}
447            onkeydown={props.onkeydown.clone()} onkeypress={props.onkeypress.clone()} onkeyup={props.onkeyup.clone()}
448            onblur={props.onblur.clone()} onchange={props.onchange.clone()} oncontextmenu={props.oncontextmenu.clone()} onfocus={props.onfocus.clone()} oninput={props.oninput.clone()} oninvalid={props.oninvalid.clone()} onreset={props.onreset.clone()} onselect={props.onselect.clone()} onsubmit={props.onsubmit.clone()}
449            onabort={props.onabort.clone()} oncanplay={props.oncanplay.clone()} oncanplaythrough={props.oncanplaythrough.clone()} oncuechange={props.oncuechange.clone()}
450            ondurationchange={props.ondurationchange.clone()} onemptied={props.onemptied.clone()} onended={props.onended.clone()} onerror={props.onerror.clone()}
451            onloadeddata={props.onloadeddata.clone()} onloadedmetadata={props.onloadedmetadata.clone()} onloadstart={props.onloadstart.clone()} onpause={props.onpause.clone()}
452            onplay={props.onplay.clone()} onplaying={props.onplaying.clone()} onprogress={props.onprogress.clone()} onratechange={props.onratechange.clone()}
453            onseeked={props.onseeked.clone()} onseeking={props.onseeking.clone()} onstalled={props.onstalled.clone()} onsuspend={props.onsuspend.clone()}
454            ontimeupdate={props.ontimeupdate.clone()} onvolumechange={props.onvolumechange.clone()} onwaiting={props.onwaiting.clone()}>
455            { for props.children.iter() }
456        </div>
457    }
458}