Add help overlay: titlebar ? button, F1 hotkey, shortcuts and tips

This commit is contained in:
megaproxy 2026-05-25 21:04:55 +01:00
parent 3cdd485627
commit b35a5b282d
4 changed files with 341 additions and 0 deletions

132
src/components/Help.css Normal file
View file

@ -0,0 +1,132 @@
.help {
position: fixed;
top: 8vh;
left: 50%;
transform: translateX(-50%);
width: min(720px, 92vw);
max-height: 84vh;
background: #161616;
color: #ccc;
border: 1px solid #2a2a2a;
border-radius: 8px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.6);
z-index: 100;
display: flex;
flex-direction: column;
overflow: hidden;
font-family: "Cascadia Mono", "JetBrains Mono", "Consolas", monospace;
}
.help-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 14px;
border-bottom: 1px solid #2a2a2a;
flex-shrink: 0;
}
.help-title {
font-weight: 600;
font-size: 13px;
}
.help-close {
background: transparent;
border: none;
color: #888;
font-size: 18px;
line-height: 1;
padding: 2px 8px;
cursor: pointer;
border-radius: 3px;
}
.help-close:hover {
background: #2a2a2a;
color: #ddd;
}
.help-body {
padding: 14px 18px;
overflow-y: auto;
font-size: 12px;
}
.help-body h3 {
margin: 18px 0 6px;
font-size: 13px;
color: #e6e6e6;
font-weight: 600;
}
.help-body h3:first-child {
margin-top: 0;
}
.help-section {
margin-bottom: 10px;
}
.help-section h4 {
margin: 8px 0 4px;
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.08em;
color: #888;
font-weight: 500;
}
.help-shortcuts {
width: 100%;
border-collapse: collapse;
}
.help-shortcuts td {
padding: 3px 4px;
vertical-align: top;
}
.help-shortcuts td.keys {
white-space: nowrap;
width: 260px;
padding-right: 12px;
}
.help-shortcuts td.desc {
color: #aaa;
line-height: 1.4;
}
.help-shortcuts kbd {
font-family: inherit;
font-size: 11px;
background: #222;
color: #cce6ff;
border: 1px solid #2a2a3a;
border-radius: 3px;
padding: 1px 6px;
white-space: nowrap;
}
.help-tips {
list-style: none;
padding: 0;
margin: 4px 0 0;
display: flex;
flex-direction: column;
gap: 6px;
}
.help-tips li {
padding: 7px 10px;
background: #1c1c1c;
border: 1px solid #2a2a2a;
border-radius: 4px;
color: #aaa;
font-size: 11px;
line-height: 1.45;
}
.help-tips strong {
color: #e6e6e6;
font-weight: 600;
}
.help-footer {
margin: 18px 0 0;
padding-top: 10px;
border-top: 1px solid #2a2a2a;
color: #666;
font-size: 11px;
line-height: 1.45;
}

78
src/components/Help.tsx Normal file
View file

@ -0,0 +1,78 @@
import { useEffect } from "react";
import { SHORTCUT_SECTIONS, TIPS } from "../lib/shortcuts";
import "./Help.css";
interface HelpProps {
onClose: () => void;
}
export default function Help({ onClose }: HelpProps) {
useEffect(() => {
function onKey(e: KeyboardEvent) {
if (e.key === "Escape") {
e.preventDefault();
onClose();
}
}
window.addEventListener("keydown", onKey);
return () => window.removeEventListener("keydown", onKey);
}, [onClose]);
return (
<>
<button
className="backdrop"
onClick={onClose}
aria-label="Close help"
></button>
<div className="help" role="dialog" aria-label="tiletopia help">
<header className="help-header">
<span className="help-title">tiletopia help</span>
<button
className="help-close"
onClick={onClose}
aria-label="Close help"
>
×
</button>
</header>
<div className="help-body">
<h3>Keyboard shortcuts</h3>
{SHORTCUT_SECTIONS.map((section) => (
<div key={section.title} className="help-section">
<h4>{section.title}</h4>
<table className="help-shortcuts">
<tbody>
{section.items.map((item) => (
<tr key={item.keys}>
<td className="keys">
<kbd>{item.keys}</kbd>
</td>
<td className="desc">{item.description}</td>
</tr>
))}
</tbody>
</table>
</div>
))}
<h3>Tips</h3>
<ul className="help-tips">
{TIPS.map((tip) => (
<li key={tip.title}>
<strong>{tip.title}.</strong> {tip.body}
</li>
))}
</ul>
<p className="help-footer">
Shortcuts work while a terminal is focused they capture the key
before xterm.js sees it. They don't fire while you're typing into
a label edit or the palette input.
</p>
</div>
</div>
</>
);
}