Replaces usage of the Asset type with AssetInput across editor components and hooks for consistency with core types. Adds default dimensions fallback for asset placement logic. Refactors UI primitives (button, sidebar, opacity control) to support forwarding refs and asChild prop, and updates imports for primitives. Updates Radix UI dependencies in package.json and bun.lock.
60 lines
2.2 KiB
TypeScript
60 lines
2.2 KiB
TypeScript
import { type AnyNodeId, useScene } from '@pascal-app/core'
|
|
import { useViewer } from '@pascal-app/viewer'
|
|
import { useEffect } from 'react'
|
|
import useEditor from '@/store/use-editor'
|
|
|
|
export const useKeyboard = () => {
|
|
useEffect(() => {
|
|
const handleKeyDown = (e: KeyboardEvent) => {
|
|
// Don't handle shortcuts if user is typing in an input
|
|
if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement) {
|
|
return
|
|
}
|
|
|
|
if (e.key === 'Escape') {
|
|
e.preventDefault()
|
|
// Emit tool:cancel event - each tool handles its own cancellation logic
|
|
// if (useEditor.getState().controlMode === 'building') {
|
|
// emitter.emit('tool:cancel', undefined)
|
|
// }
|
|
// if (selectedNodeIds.length > 0) {
|
|
// handleClear()
|
|
// }
|
|
} else if (e.key === '1' && !e.metaKey && !e.ctrlKey) {
|
|
e.preventDefault()
|
|
useEditor.getState().setPhase('site')
|
|
useEditor.getState().setMode('select')
|
|
} else if (e.key === '2' && !e.metaKey && !e.ctrlKey) {
|
|
e.preventDefault()
|
|
useEditor.getState().setPhase('structure')
|
|
useEditor.getState().setMode('select')
|
|
} else if (e.key === '3' && !e.metaKey && !e.ctrlKey) {
|
|
e.preventDefault()
|
|
useEditor.getState().setPhase('furnish')
|
|
useEditor.getState().setMode('select')
|
|
} if (e.key === 'v' && !e.metaKey && !e.ctrlKey) {
|
|
e.preventDefault()
|
|
useEditor.getState().setMode('select')
|
|
} else if (e.key === 'z' && (e.metaKey || e.ctrlKey)) {
|
|
e.preventDefault()
|
|
useScene.temporal.getState().undo()
|
|
} else if (e.key === 'Z' && e.shiftKey && (e.metaKey || e.ctrlKey)) {
|
|
e.preventDefault()
|
|
useScene.temporal.getState().redo()
|
|
} else if (e.key === 'Delete' || e.key === 'Backspace') {
|
|
e.preventDefault()
|
|
|
|
const selectedNodeIds = useViewer.getState().selection.selectedIds as AnyNodeId[]
|
|
|
|
if (selectedNodeIds.length > 0) {
|
|
useScene.getState().deleteNodes(selectedNodeIds)
|
|
}
|
|
}
|
|
}
|
|
window.addEventListener('keydown', handleKeyDown)
|
|
return () => window.removeEventListener('keydown', handleKeyDown)
|
|
}, [])
|
|
|
|
return null
|
|
}
|