add keyboard shortcuts

This commit is contained in:
Sanster 2022-02-07 22:25:24 +08:00
parent 56238c5068
commit 3db21e7e95
4 changed files with 91 additions and 6 deletions

View File

@ -1,12 +1,14 @@
import { ArrowLeftIcon } from '@heroicons/react/outline' import { ArrowLeftIcon } from '@heroicons/react/outline'
import React, { useState } from 'react' import React, { useState } from 'react'
import { useWindowSize } from 'react-use' import { useToggle, useWindowSize } from 'react-use'
import Button from './components/Button' import Button from './components/Button'
import FileSelect from './components/FileSelect' import FileSelect from './components/FileSelect'
import ShortcutsModal from './components/ShortcutsModal'
import Editor from './Editor' import Editor from './Editor'
function App() { function App() {
const [file, setFile] = useState<File>() const [file, setFile] = useState<File>()
const [showShortcuts, toggleShowShortcuts] = useToggle(false)
const windowSize = useWindowSize() const windowSize = useWindowSize()
return ( return (
@ -27,6 +29,7 @@ function App() {
{file ? ( {file ? (
<Button <Button
onClick={toggleShowShortcuts}
icon={ icon={
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
@ -57,6 +60,8 @@ function App() {
)} )}
</header> </header>
{showShortcuts && <ShortcutsModal onClose={toggleShowShortcuts} />}
<main <main
className={[ className={[
'h-full flex flex-1 flex-col sm:items-center sm:justify-center overflow-hidden', 'h-full flex flex-1 flex-col sm:items-center sm:justify-center overflow-hidden',

View File

@ -35,11 +35,17 @@ export default function Button(props: ButtonProps) {
if (!primary && !active) { if (!primary && !active) {
background = 'hover:bg-primary' background = 'hover:bg-primary'
} }
const blurOnClick = (e: React.MouseEvent<HTMLDivElement>) => {
e.currentTarget.blur()
onClick?.()
}
return ( return (
<div <div
role="button" role="button"
onKeyDown={onKeyDown} onKeyDown={onKeyDown}
onClick={onClick} onClick={blurOnClick}
onPointerDown={(ev: React.PointerEvent<HTMLDivElement>) => { onPointerDown={(ev: React.PointerEvent<HTMLDivElement>) => {
setActive(true) setActive(true)
onDown?.(ev.nativeEvent) onDown?.(ev.nativeEvent)

View File

@ -1,19 +1,46 @@
import React, { ReactNode } from 'react' import { XIcon } from '@heroicons/react/outline'
import React, { ReactNode, useRef } from 'react'
import { useClickAway } from 'react-use'
import Button from './Button'
interface ModalProps { interface ModalProps {
children?: ReactNode children?: ReactNode
onClose?: () => void
className?: string
} }
export default function Modal(props: ModalProps) { export default function Modal(props: ModalProps) {
const { children } = props const { children, onClose, className } = props
const ref = useRef(null)
useClickAway(ref, () => {
onClose?.()
})
return ( return (
<div <div
className={[ className={[
'absolute w-full h-full flex justify-center items-center', 'absolute w-full h-full flex justify-center items-center',
'bg-white bg-opacity-40 backdrop-filter backdrop-blur-md', 'z-20',
'bg-gray-300 bg-opacity-40 backdrop-filter backdrop-blur-md',
].join(' ')} ].join(' ')}
> >
<div className="bg-primary p-16 max-w-4xl">{children}</div> <div
ref={ref}
className={`bg-white max-w-4xl relative rounded-md shadow-md ${
className || 'p-8 sm:p-12'
}`}
>
<Button
icon={<XIcon className="w-6 h-6" />}
className={[
'absolute right-4 top-4 rounded-full bg-gray-100 w-10 h-10',
'flex justify-center items-center py-0 px-0 sm:px-0',
].join(' ')}
onClick={onClose}
/>
{children}
</div>
</div> </div>
) )
} }

View File

@ -0,0 +1,47 @@
import { ArrowLeftIcon } from '@heroicons/react/outline'
import React, { ReactNode } from 'react'
import Modal from './Modal'
interface Shortcut {
children: ReactNode
content: string
}
function ShortCut(props: Shortcut) {
const { children, content } = props
return (
<div className="h-full flex flex-row space-x-6 justify-between">
<div className="mr-12 border-2 rounded-xl px-2 py-1">{children}</div>
<div className="flex flex-col justify-center">{content}</div>
</div>
)
}
interface ShortcutsModalProps {
onClose?: () => void
}
export default function ShortcutsModal(props: ShortcutsModalProps) {
const { onClose } = props
return (
<Modal onClose={onClose} className="h-full sm:h-auto p-0 sm:p-0">
<div className="h-full sm:h-auto flex flex-col sm:flex-row">
<div className="flex sm:p-14 flex flex-col justify-center space-y-6">
<ShortCut content="Enable multi-stroke mask drawing">
<p>Hold Cmd/Ctrl</p>
</ShortCut>
<ShortCut content="Enable panning">
<p>Hold Space</p>
</ShortCut>
<ShortCut content="View original image">
<p>Hold Tab</p>
</ShortCut>
<ShortCut content="Reset zoom/pan & Cancel mask drawing">
<p>Esc</p>
</ShortCut>
</div>
</div>
</Modal>
)
}