feat: add Windows shortcuts and OS toggle to WelcomeView
- Define mac/win key variants for all 8 shortcuts (⌘→Ctrl, ⌘⇧Z→Ctrl+Y) - Auto-detect OS on mount via navigator.platform - Add macOS/Windows pill toggle above shortcuts table Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
999d5e1b82
commit
7c1f8f8726
@ -1,3 +1,4 @@
|
|||||||
|
import { useState } from 'react'
|
||||||
import {
|
import {
|
||||||
FileText, Folder, Slash, MousePointer, Save,
|
FileText, Folder, Slash, MousePointer, Save,
|
||||||
Search, Moon, Plus, Hash, Star, Image, Code2,
|
Search, Moon, Plus, Hash, Star, Image, Code2,
|
||||||
@ -73,19 +74,24 @@ const FEATURES = [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
const SHORTCUTS = [
|
const SHORTCUTS: { mac: string[]; win: string[]; desc: string }[] = [
|
||||||
{ desc: '粗体', mac: ['⌘', 'B'], win: ['Ctrl', 'B'] },
|
{ mac: ['⌘', 'B'], win: ['Ctrl', 'B'], desc: '粗体' },
|
||||||
{ desc: '斜体', mac: ['⌘', 'I'], win: ['Ctrl', 'I'] },
|
{ mac: ['⌘', 'I'], win: ['Ctrl', 'I'], desc: '斜体' },
|
||||||
{ desc: '下划线', mac: ['⌘', 'U'], win: ['Ctrl', 'U'] },
|
{ mac: ['⌘', 'U'], win: ['Ctrl', 'U'], desc: '下划线' },
|
||||||
{ desc: '行内代码', mac: ['⌘', 'E'], win: ['Ctrl', 'E'] },
|
{ mac: ['⌘', 'E'], win: ['Ctrl', 'E'], desc: '行内代码' },
|
||||||
{ desc: '撤销', mac: ['⌘', 'Z'], win: ['Ctrl', 'Z'] },
|
{ mac: ['⌘', 'Z'], win: ['Ctrl', 'Z'], desc: '撤销' },
|
||||||
{ desc: '重做', mac: ['⌘', '⇧', 'Z'], win: ['Ctrl', 'Y'] },
|
{ mac: ['⌘', '⇧', 'Z'], win: ['Ctrl', 'Y'], desc: '重做' },
|
||||||
{ desc: '命令菜单', mac: ['/'], win: ['/'] },
|
{ mac: ['/'], win: ['/'], desc: '命令菜单' },
|
||||||
{ desc: '退出专注模式', mac: ['Esc'], win: ['Esc'] },
|
{ mac: ['Esc'], win: ['Esc'], desc: '退出专注模式' },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
function detectOS(): 'mac' | 'win' {
|
||||||
|
return /mac/i.test(navigator.platform) ? 'mac' : 'win'
|
||||||
|
}
|
||||||
|
|
||||||
export function WelcomeView() {
|
export function WelcomeView() {
|
||||||
const { createNote } = useAppStore()
|
const { createNote } = useAppStore()
|
||||||
|
const [os, setOs] = useState<'mac' | 'win'>(detectOS)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@ -158,59 +164,49 @@ export function WelcomeView() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Shortcuts */}
|
{/* Shortcuts */}
|
||||||
<h2
|
<div className="flex items-center justify-between mb-4">
|
||||||
className="text-xs font-semibold uppercase tracking-widest mb-4"
|
<h2
|
||||||
style={{ color: 'var(--text-faint)' }}
|
className="text-xs font-semibold uppercase tracking-widest"
|
||||||
>
|
style={{ color: 'var(--text-faint)' }}
|
||||||
常用快捷键
|
|
||||||
</h2>
|
|
||||||
<div className="rounded-xl overflow-hidden" style={{ border: '1px solid var(--border)' }}>
|
|
||||||
{/* Header */}
|
|
||||||
<div
|
|
||||||
className="grid px-5 py-2 text-xs font-semibold uppercase tracking-wider"
|
|
||||||
style={{
|
|
||||||
gridTemplateColumns: '1fr auto auto',
|
|
||||||
gap: '2rem',
|
|
||||||
background: 'var(--bg-muted)',
|
|
||||||
color: 'var(--text-faint)',
|
|
||||||
borderBottom: '1px solid var(--border)',
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<span>操作</span>
|
常用快捷键
|
||||||
<span>macOS</span>
|
</h2>
|
||||||
<span>Windows</span>
|
<div
|
||||||
|
className="flex items-center rounded-lg p-0.5 text-xs"
|
||||||
|
style={{ background: 'var(--bg-muted)', border: '1px solid var(--border)' }}
|
||||||
|
>
|
||||||
|
{(['mac', 'win'] as const).map(opt => (
|
||||||
|
<button
|
||||||
|
key={opt}
|
||||||
|
onClick={() => setOs(opt)}
|
||||||
|
className="px-2.5 py-1 rounded-md font-medium transition-colors"
|
||||||
|
style={{
|
||||||
|
background: os === opt ? 'var(--bg)' : 'transparent',
|
||||||
|
color: os === opt ? 'var(--text)' : 'var(--text-faint)',
|
||||||
|
boxShadow: os === opt ? '0 1px 3px rgba(0,0,0,0.08)' : 'none',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{opt === 'mac' ? 'macOS' : 'Windows'}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="rounded-xl overflow-hidden"
|
||||||
|
style={{ border: '1px solid var(--border)' }}
|
||||||
|
>
|
||||||
{SHORTCUTS.map((s, i) => (
|
{SHORTCUTS.map((s, i) => (
|
||||||
<div
|
<div
|
||||||
key={s.desc}
|
key={s.desc}
|
||||||
className="grid items-center px-5 py-3"
|
className="flex items-center justify-between px-5 py-3"
|
||||||
style={{
|
style={{
|
||||||
gridTemplateColumns: '1fr auto auto',
|
|
||||||
gap: '2rem',
|
|
||||||
borderTop: i > 0 ? '1px solid var(--border)' : 'none',
|
borderTop: i > 0 ? '1px solid var(--border)' : 'none',
|
||||||
background: 'var(--bg-subtle)',
|
background: 'var(--bg-subtle)',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span className="text-sm" style={{ color: 'var(--text-muted)' }}>{s.desc}</span>
|
<span className="text-sm" style={{ color: 'var(--text-muted)' }}>{s.desc}</span>
|
||||||
<div className="flex items-center gap-1 justify-end">
|
<div className="flex items-center gap-1">
|
||||||
{s.mac.map(k => (
|
{s[os].map(k => (
|
||||||
<kbd
|
|
||||||
key={k}
|
|
||||||
className="inline-flex items-center justify-center px-2 py-0.5 rounded text-xs font-mono"
|
|
||||||
style={{
|
|
||||||
background: 'var(--bg)',
|
|
||||||
border: '1px solid var(--border)',
|
|
||||||
color: 'var(--text)',
|
|
||||||
minWidth: 28,
|
|
||||||
boxShadow: '0 1px 0 var(--border)',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{k}
|
|
||||||
</kbd>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center gap-1 justify-end">
|
|
||||||
{s.win.map(k => (
|
|
||||||
<kbd
|
<kbd
|
||||||
key={k}
|
key={k}
|
||||||
className="inline-flex items-center justify-center px-2 py-0.5 rounded text-xs font-mono"
|
className="inline-flex items-center justify-center px-2 py-0.5 rounded text-xs font-mono"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user