主题与快捷键:透明主题真透明 + 完整 Typora 快捷键
This commit is contained in:
@@ -1,8 +1,14 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useKeymap, formatCombo, type Scope } from './keymap-service';
|
||||
import { useKeymap, formatCombo } from './keymap-service';
|
||||
|
||||
const SCOPE_LABELS: Record<Scope, string> = { global: '全局', app: '应用级', editor: '编辑器' };
|
||||
const SCOPE_ORDER: Scope[] = ['global', 'app', 'editor'];
|
||||
// 按 Typora 官方菜单分组的快捷键速查
|
||||
const GROUPS: { label: string; ids: string[] }[] = [
|
||||
{ label: '📁 文件', ids: ['newDoc', 'newWindow', 'openFile', 'quickOpen', 'save', 'saveAs', 'toggleSettings', 'closeTab', 'reopenTab'] },
|
||||
{ label: '✏️ 基础编辑', ids: ['find', 'replace', 'copyMd', 'pastePlain', 'selectLine', 'selectWord', 'selectSameFormat', 'deleteWord', 'docStart', 'docEnd'] },
|
||||
{ label: '📝 Markdown 格式', ids: ['bold', 'italic', 'underline', 'strike', 'inlineCode', 'link', 'insertImage', 'clearFormat'] },
|
||||
{ label: '📑 段落、标题、块', ids: ['heading1', 'heading2', 'heading3', 'heading4', 'heading5', 'heading6', 'paragraph', 'headingUp', 'headingDown', 'blockquote', 'bulletList', 'orderedList', 'codeBlock', 'mathBlock', 'table', 'indent', 'outdent', 'moveUp', 'moveDown'] },
|
||||
{ label: '👁️ 视图', ids: ['toggleSidebar', 'toggleOutline', 'toggleInfo', 'fileTree', 'focusMode', 'typewriter', 'fullscreen', 'focusSearch', 'toggleCheat'] },
|
||||
];
|
||||
|
||||
export function CheatSheet({ onClose }: { onClose: () => void }) {
|
||||
const bindings = useKeymap(s => s.bindings);
|
||||
@@ -12,16 +18,17 @@ export function CheatSheet({ onClose }: { onClose: () => void }) {
|
||||
window.addEventListener('keydown', onEsc, true);
|
||||
return () => window.removeEventListener('keydown', onEsc, true);
|
||||
}, [onClose]);
|
||||
const byId = new Map(bindings.map(b => [b.id, b] as const));
|
||||
return (
|
||||
<div onClick={e => { if (e.target === e.currentTarget) onClose(); }} style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.5)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 1500 }}>
|
||||
<div className="panel-slide-in" style={{ width: 480, maxHeight: '80vh', overflow: 'auto', background: 'var(--bg-secondary)', border: '1px solid var(--control-border)', borderRadius: 10, padding: 20, boxShadow: '0 8px 32px rgba(0,0,0,0.5)' }}>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 16 }}><strong style={{ fontSize: 15 }}>快捷键速查</strong><button onClick={onClose} style={{ background: 'none', border: 'none', color: 'var(--text-tertiary)', cursor: 'pointer', fontSize: 16 }}>✕</button></div>
|
||||
{SCOPE_ORDER.map(scope => {
|
||||
const items = bindings.filter(b => b.scope === scope);
|
||||
<div className="panel-slide-in" style={{ width: 520, maxHeight: '80vh', overflow: 'auto', background: 'var(--bg-secondary)', border: '1px solid var(--control-border)', borderRadius: 10, padding: 20, boxShadow: '0 8px 32px rgba(0,0,0,0.5)' }}>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 16 }}><strong style={{ fontSize: 15 }}>快捷键速查(Typora 标准)</strong><button onClick={onClose} style={{ background: 'none', border: 'none', color: 'var(--text-tertiary)', cursor: 'pointer', fontSize: 16 }}>✕</button></div>
|
||||
{GROUPS.map(g => {
|
||||
const items = g.ids.map(id => byId.get(id)).filter((b): b is NonNullable<typeof b> => !!b);
|
||||
if (items.length === 0) return null;
|
||||
return (
|
||||
<div key={scope} style={{ marginBottom: 14 }}>
|
||||
<div style={{ opacity: 0.5, fontSize: 12, marginBottom: 6 }}>{SCOPE_LABELS[scope]}</div>
|
||||
<div key={g.label} style={{ marginBottom: 14 }}>
|
||||
<div style={{ opacity: 0.5, fontSize: 12, marginBottom: 6 }}>{g.label}</div>
|
||||
{items.map(b => (
|
||||
<div key={b.id} style={{ display: 'flex', justifyContent: 'space-between', padding: '3px 0', fontSize: 13 }}>
|
||||
<span style={{ color: 'var(--text-primary)' }}>{b.label}</span>
|
||||
|
||||
Reference in New Issue
Block a user