ui_storybook/components/shell/
drop_zone.rs1use leptos::prelude::*;
9
10#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
11pub enum DropZoneState {
12 #[default]
13 Idle,
14 Active,
15}
16
17impl DropZoneState {
18 fn css(self) -> &'static str {
19 match self {
20 DropZoneState::Idle => "drop-zone-idle",
21 DropZoneState::Active => "drop-zone-active",
22 }
23 }
24
25 fn glyph(self) -> &'static str {
26 match self {
27 DropZoneState::Idle => "⤓",
28 DropZoneState::Active => "⇣",
29 }
30 }
31
32 fn headline(self) -> &'static str {
33 match self {
34 DropZoneState::Idle => "Drop a recording here",
35 DropZoneState::Active => "Release to import",
36 }
37 }
38
39 fn subtext(self) -> &'static str {
40 match self {
41 DropZoneState::Idle => "MP4, MOV, or any QuickTime-compatible video",
42 DropZoneState::Active => "Will open in the editor",
43 }
44 }
45}
46
47#[component]
48pub fn DropZone(
49 #[prop(optional)] state: DropZoneState,
50 #[prop(optional, into)] hint: String,
51) -> impl IntoView {
52 let class = format!("drop-zone {}", state.css());
53 let glyph = state.glyph();
54 let headline = state.headline();
55 let subtext = state.subtext();
56 let has_hint = !hint.is_empty();
57 view! {
58 <div class=class role="region" aria-label="Recording drop zone">
59 <div class="drop-zone-glyph">{glyph}</div>
60 <div class="drop-zone-headline">{headline}</div>
61 <div class="drop-zone-subtext">{subtext}</div>
62 <Show when=move || has_hint>
63 <div class="drop-zone-hint">{hint.clone()}</div>
64 </Show>
65 </div>
66 }
67}