ui_storybook/stories/
library.rs1use leptos::prelude::*;
5
6use crate::components::library::{LibraryGrid, LibrarySidebar, RecordingCard, RecordingCardState};
7use crate::fixtures::library::{
8 sample_library_grid, sample_library_grid_empty, sample_library_grid_list_mode,
9 sample_library_sidebar, sample_library_sidebar_high_storage,
10 sample_library_sidebar_inbox_active, sample_recording_cards,
11};
12
13use super::{Story, StoryViewport, render};
14
15const RAIL_W: u16 = 260;
16const RAIL_H: u16 = 620;
17const GRID_W: u16 = 880;
18const GRID_H: u16 = 520;
19const CARD_W: u16 = 360;
20const CARD_H: u16 = 280;
21
22#[must_use]
24pub fn stories() -> Vec<Story> {
25 vec![
26 story(
27 "library-sidebar-default",
28 "Library sidebar — default",
29 render_default,
30 ),
31 story(
32 "library-sidebar-inbox-active",
33 "Library sidebar — inbox active",
34 render_inbox,
35 ),
36 story(
37 "library-sidebar-high-storage",
38 "Library sidebar — 95% storage",
39 render_high_storage,
40 ),
41 story(
42 "library-sidebar-empty-spaces",
43 "Library sidebar — no spaces",
44 render_empty_spaces,
45 ),
46 story(
47 "library-sidebar-long-labels",
48 "Library sidebar — overflow labels",
49 render_long_labels,
50 ),
51 card_story(
52 "recording-card-ready",
53 "Recording card — ready",
54 render_card_ready,
55 ),
56 card_story(
57 "recording-card-processing",
58 "Recording card — processing",
59 render_card_processing,
60 ),
61 card_story(
62 "recording-card-empty-thumbnail",
63 "Recording card — missing thumbnail",
64 render_card_empty_thumb,
65 ),
66 grid_story(
67 "library-grid-default",
68 "Library grid — default",
69 render_grid_default,
70 ),
71 grid_story(
72 "library-grid-empty",
73 "Library grid — empty state",
74 render_grid_empty,
75 ),
76 grid_story(
77 "library-grid-list-mode",
78 "Library grid — list mode",
79 render_grid_list,
80 ),
81 ]
82}
83
84fn card_story(id: &'static str, title: &'static str, render: fn() -> String) -> Story {
85 Story {
86 id,
87 category: "Library",
88 title,
89 viewport: StoryViewport::Fixed {
90 width: CARD_W,
91 height: CARD_H,
92 },
93 render,
94 }
95}
96
97fn grid_story(id: &'static str, title: &'static str, render: fn() -> String) -> Story {
98 Story {
99 id,
100 category: "Library",
101 title,
102 viewport: StoryViewport::Fixed {
103 width: GRID_W,
104 height: GRID_H,
105 },
106 render,
107 }
108}
109
110fn story(id: &'static str, title: &'static str, render: fn() -> String) -> Story {
111 Story {
112 id,
113 category: "Library",
114 title,
115 viewport: StoryViewport::Fixed {
116 width: RAIL_W,
117 height: RAIL_H,
118 },
119 render,
120 }
121}
122
123fn render_default() -> String {
124 render(view! { <LibrarySidebar view=sample_library_sidebar(3) /> })
125}
126
127fn render_inbox() -> String {
128 render(view! { <LibrarySidebar view=sample_library_sidebar_inbox_active() /> })
129}
130
131fn render_high_storage() -> String {
132 render(view! { <LibrarySidebar view=sample_library_sidebar_high_storage() /> })
133}
134
135fn render_empty_spaces() -> String {
136 let mut v = sample_library_sidebar(0);
137 v.sections.retain(|s| s.heading != "SPACES");
138 render(view! { <LibrarySidebar view=v /> })
139}
140
141fn render_long_labels() -> String {
142 let mut v = sample_library_sidebar(99);
143 if let Some(item) = v.primary.iter_mut().find(|i| i.id == "shared") {
144 item.label = "Shared with me — Northwind Studio quarterly review";
145 }
146 render(view! { <LibrarySidebar view=v /> })
147}
148
149fn render_card_ready() -> String {
150 let cards = sample_recording_cards();
151 let card = cards.into_iter().next().expect("at least one card");
152 render(view! { <RecordingCard view=card /> })
153}
154
155fn render_card_processing() -> String {
156 let cards = sample_recording_cards();
157 let mut card = cards.into_iter().nth(1).expect("processing fixture");
158 card.state = RecordingCardState::Processing { percent: 42 };
159 render(view! { <RecordingCard view=card /> })
160}
161
162fn render_card_empty_thumb() -> String {
163 let cards = sample_recording_cards();
164 let card = cards.into_iter().last().expect("empty-thumb fixture");
165 render(view! { <RecordingCard view=card /> })
166}
167
168fn render_grid_default() -> String {
169 render(view! { <LibraryGrid view=sample_library_grid() /> })
170}
171
172fn render_grid_empty() -> String {
173 render(view! { <LibraryGrid view=sample_library_grid_empty() /> })
174}
175
176fn render_grid_list() -> String {
177 render(view! { <LibraryGrid view=sample_library_grid_list_mode() /> })
178}