ui_storybook/components/primitives/
icon_tile.rs1use leptos::prelude::*;
8
9#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
11pub enum IconTileKind {
12 #[default]
14 Workspace,
15 Device,
17 App,
19 Action,
22 User,
24}
25
26impl IconTileKind {
27 #[must_use]
29 pub fn css(self) -> &'static str {
30 match self {
31 IconTileKind::Workspace => "icon-tile-workspace",
32 IconTileKind::Device => "icon-tile-device",
33 IconTileKind::App => "icon-tile-app",
34 IconTileKind::Action => "icon-tile-action",
35 IconTileKind::User => "icon-tile-user",
36 }
37 }
38}
39
40#[component]
41pub fn IconTile(
42 #[prop(optional)] kind: IconTileKind,
43 #[prop(optional, into)] extra_class: String,
44 children: Children,
45) -> impl IntoView {
46 let class = format!(
47 "icon-tile {}{}{}",
48 kind.css(),
49 if extra_class.is_empty() { "" } else { " " },
50 extra_class,
51 );
52 view! { <span class=class aria-hidden="true">{children()}</span> }
53}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58
59 #[test]
60 fn each_kind_has_unique_class() {
61 let classes = [
62 IconTileKind::Workspace.css(),
63 IconTileKind::Device.css(),
64 IconTileKind::App.css(),
65 IconTileKind::Action.css(),
66 IconTileKind::User.css(),
67 ];
68 let mut sorted = classes.to_vec();
69 sorted.sort_unstable();
70 sorted.dedup();
71 assert_eq!(sorted.len(), classes.len());
72 }
73
74 #[test]
75 fn each_class_starts_with_icon_tile_prefix() {
76 for k in [
77 IconTileKind::Workspace,
78 IconTileKind::Device,
79 IconTileKind::App,
80 IconTileKind::Action,
81 IconTileKind::User,
82 ] {
83 assert!(k.css().starts_with("icon-tile-"));
84 }
85 }
86}