chattyness/crates/chattyness-user-ui/src/components/hotkey_help.rs

106 lines
4 KiB
Rust

//! Hotkey help overlay component.
//!
//! Displays available keyboard shortcuts while held.
use leptos::prelude::*;
/// Hotkey help overlay that shows available keyboard shortcuts.
///
/// This component displays while the user holds down the `?` key.
#[component]
pub fn HotkeyHelp(
/// Whether the help overlay is visible.
#[prop(into)]
visible: Signal<bool>,
) -> impl IntoView {
let outer_class = move || {
if visible.get() {
"fixed inset-0 z-50 flex items-center justify-center pointer-events-none"
} else {
"hidden"
}
};
view! {
<div class=outer_class>
// Semi-transparent backdrop
<div class="absolute inset-0 bg-black/60" aria-hidden="true" />
// Help content
<div class="relative bg-gray-800/95 backdrop-blur-sm rounded-lg shadow-2xl p-6 border border-gray-600 max-w-md">
<h2 class="text-lg font-bold text-white mb-4 text-center">
"Keyboard Shortcuts"
</h2>
<div class="grid grid-cols-2 gap-x-6 gap-y-2 text-sm">
// Navigation & Chat
<div class="col-span-2 text-gray-400 font-medium mt-2 first:mt-0">
"Navigation & Chat"
</div>
<HotkeyRow key="Space" description="Focus chat input" />
<HotkeyRow key=":" description="Open emote commands" />
<HotkeyRow key="/" description="Open slash commands" />
<HotkeyRow key="Esc" description="Close/unfocus" />
// Popups
<div class="col-span-2 text-gray-400 font-medium mt-3">
"Popups"
</div>
<HotkeyRow key="s" description="Settings" />
<HotkeyRow key="i" description="Inventory" />
<HotkeyRow key="k" description="Keybindings" />
<HotkeyRow key="a" description="Avatar editor" />
<HotkeyRow key="l" description="Message log" />
// Emotions
<div class="col-span-2 text-gray-400 font-medium mt-3">
"Emotions"
</div>
<div class="col-span-2 text-gray-300">
<kbd class="px-1.5 py-0.5 bg-gray-700 rounded text-xs">"e"</kbd>
" + "
<kbd class="px-1.5 py-0.5 bg-gray-700 rounded text-xs">"0-9"</kbd>
" / "
<kbd class="px-1.5 py-0.5 bg-gray-700 rounded text-xs">"q"</kbd>
" / "
<kbd class="px-1.5 py-0.5 bg-gray-700 rounded text-xs">"w"</kbd>
<span class="text-gray-500 ml-2">"Apply emotion"</span>
</div>
// View controls
<div class="col-span-2 text-gray-400 font-medium mt-3">
"View (when panning enabled)"
</div>
<HotkeyRow key="Arrows" description="Pan view" />
<HotkeyRow key="+/-" description="Zoom in/out" />
</div>
<div class="mt-4 pt-3 border-t border-gray-600 text-xs text-gray-500 text-center">
"Release " <kbd class="px-1.5 py-0.5 bg-gray-700 rounded">"?"</kbd> " to close"
</div>
</div>
</div>
}
}
/// A single hotkey row with key and description.
#[component]
fn HotkeyRow(
/// The key or key combination.
key: &'static str,
/// Description of what the key does.
description: &'static str,
) -> impl IntoView {
view! {
<div class="contents">
<div class="text-right">
<kbd class="px-1.5 py-0.5 bg-gray-700 rounded text-xs text-gray-200">
{key}
</kbd>
</div>
<div class="text-gray-300">
{description}
</div>
</div>
}
}