Skip to main content

orbital_base_components/form/info_label/
base.rs

1use leptos::prelude::*;
2
3use crate::form::{BaseLabel, LabelSize, LabelWeight};
4use crate::icon::BaseIcon;
5use crate::overlay::{
6    BasePopover, OverlayAppearance, OverlayPanelSize, OverlayTrigger, OverlayTriggerType, Placement,
7};
8
9#[slot]
10pub struct InfoLabelInfo {
11    pub children: Children,
12}
13
14/// Headless info label composed from `BaseLabel` + `BasePopover` + `BaseIcon`.
15///
16/// Panel content is rendered without a Material surface; prefer the core `InfoLabel` control, which composes the orbital `Popover` so the panel gets `FloatingPanel` styling.
17#[component]
18pub fn BaseInfoLabel(
19    #[prop(optional, into)] class: MaybeProp<String>,
20    #[prop(optional, into)] size: Signal<LabelSize>,
21    #[prop(optional, into)] weight: Signal<LabelWeight>,
22    #[prop(optional, into)] required: Signal<bool>,
23    #[prop(optional, into)] disabled: Signal<bool>,
24    #[prop(optional, into)] html_for: MaybeProp<String>,
25    #[prop(into)] icon: icondata_core::Icon,
26    #[prop(optional)] trigger_type: OverlayTriggerType,
27    #[prop(optional)] position: Placement,
28    #[prop(optional)] appearance: OverlayAppearance,
29    #[prop(optional)] panel_size: OverlayPanelSize,
30    info_label_info: InfoLabelInfo,
31    children: Children,
32) -> impl IntoView {
33    let size_class = Signal::derive(move || format!("orbital-label--{}", size.get().as_str()));
34    let weight_class = Signal::derive(move || format!("orbital-label--{}", weight.get().as_str()));
35    let wrapper_class = Signal::derive(move || {
36        let mut parts = vec!["orbital-info-label".to_string()];
37        if let Some(extra) = class.get() {
38            if !extra.is_empty() {
39                parts.push(extra);
40            }
41        }
42        parts.join(" ")
43    });
44
45    view! {
46        <span class=wrapper_class>
47            <BaseLabel
48                class="orbital-info-label__label"
49                size=size_class
50                weight=weight_class
51                label_size=size
52                label_weight=weight
53                required=required
54                disabled=disabled
55                attr_for=html_for
56            >
57                {children()}
58            </BaseLabel>
59            <BasePopover
60                class="orbital-info-label__popover"
61                trigger_type=trigger_type
62                placement=position
63                appearance=appearance
64                size=panel_size
65            >
66                <OverlayTrigger slot>
67                    <button
68                        type="button"
69                        class="orbital-info-label__info-button"
70                        aria-label="More information"
71                    >
72                        <BaseIcon icon=icon />
73                    </button>
74                </OverlayTrigger>
75                <div class="orbital-info-label__content">
76                    {(info_label_info.children)()}
77                </div>
78            </BasePopover>
79        </span>
80    }
81}