Skip to main content

ui_storybook/components/shell/
workspace_badge.rs

1//! `WorkspaceBadge` — top-of-rail workspace marker (M-UI.2 / AUT-122).
2//!
3//! Compact square tile with the active workspace's monogram. Includes a
4//! small chevron glyph that signals "click for the workspace switcher".
5//! Purely visual; the switcher menu is the parent's responsibility
6//! (UI-05).
7
8use leptos::prelude::*;
9
10/// View-model for the workspace badge at the top of the rail.
11#[derive(Debug, Clone, PartialEq, Eq)]
12pub struct WorkspaceBadgeView {
13    /// Stable id (matches the workspace fixture's id).
14    pub id: &'static str,
15    /// 2-letter monogram displayed inside the tile.
16    pub monogram: &'static str,
17    /// Workspace label, used for the accessible title.
18    pub label: &'static str,
19    /// Optional accent color for the tile background (CSS-color
20    /// string). Defaults to the brand red when `None`.
21    pub accent: Option<&'static str>,
22}
23
24#[component]
25pub fn WorkspaceBadge(
26    view: WorkspaceBadgeView,
27    /// `true` when the workspace-switcher popover is open. Adds a
28    /// `workspace-badge-open` class for the parent menu's open state.
29    #[prop(optional)]
30    open: bool,
31) -> impl IntoView {
32    let style = view
33        .accent
34        .map(|a| format!("background:{a}"))
35        .unwrap_or_default();
36    let class = if open {
37        "workspace-badge workspace-badge-open"
38    } else {
39        "workspace-badge"
40    };
41    view! {
42        <button class=class title=view.label aria-haspopup="menu" aria-expanded=open>
43            <span class="workspace-badge-tile" style=style>{view.monogram}</span>
44            <span class="workspace-badge-chevron" aria-hidden="true">"▾"</span>
45        </button>
46    }
47}