All files / web/src/components/toys/shared KeyboardShortcutsOverlay.tsx

0% Statements 0/127
0% Branches 0/1
0% Functions 0/1
0% Lines 0/127

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128                                                                                                                                                                                                                                                               
'use client'

import { useEffect, useCallback } from 'react'

export interface ShortcutEntry {
  key: string
  description: string
}

interface KeyboardShortcutsOverlayProps {
  shortcuts: ShortcutEntry[]
  onClose: () => void
  isDark: boolean
}

/**
 * Modal overlay showing a list of keyboard shortcuts.
 * Press `?` to open (handled by parent), `Esc` or click backdrop to close.
 */
export function KeyboardShortcutsOverlay({
  shortcuts,
  onClose,
  isDark,
}: KeyboardShortcutsOverlayProps) {
  const handleKeyDown = useCallback(
    (e: KeyboardEvent) => {
      if (e.key === 'Escape' || e.key === '?') {
        e.preventDefault()
        onClose()
      }
    },
    [onClose]
  )

  useEffect(() => {
    window.addEventListener('keydown', handleKeyDown)
    return () => window.removeEventListener('keydown', handleKeyDown)
  }, [handleKeyDown])

  return (
    <div
      data-element="keyboard-shortcuts-overlay"
      onClick={onClose}
      style={{
        position: 'absolute',
        inset: 0,
        zIndex: 200,
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        backgroundColor: 'rgba(0,0,0,0.6)',
        backdropFilter: 'blur(4px)',
      }}
    >
      <div
        data-element="keyboard-shortcuts-card"
        onClick={(e) => e.stopPropagation()}
        style={{
          backgroundColor: isDark ? '#1e293b' : '#ffffff',
          color: isDark ? '#e2e8f0' : '#1e293b',
          borderRadius: 12,
          padding: '20px 28px',
          boxShadow: '0 8px 32px rgba(0,0,0,0.3)',
          maxWidth: 360,
          width: '90%',
          fontFamily: 'system-ui, sans-serif',
        }}
      >
        <div
          style={{
            display: 'flex',
            justifyContent: 'space-between',
            alignItems: 'center',
            marginBottom: 16,
          }}
        >
          <span style={{ fontWeight: 700, fontSize: 16 }}>Keyboard Shortcuts</span>
          <button
            data-action="close-shortcuts"
            onClick={onClose}
            style={{
              background: 'none',
              border: 'none',
              cursor: 'pointer',
              color: isDark ? '#94a3b8' : '#64748b',
              fontSize: 20,
              lineHeight: 1,
              padding: '2px 6px',
            }}
          >
            &times;
          </button>
        </div>
        {shortcuts.map(({ key, description }) => (
          <div
            key={key}
            style={{
              display: 'flex',
              justifyContent: 'space-between',
              alignItems: 'center',
              padding: '5px 0',
            }}
          >
            <kbd
              style={{
                backgroundColor: isDark ? '#334155' : '#f1f5f9',
                color: isDark ? '#e2e8f0' : '#334155',
                borderRadius: 4,
                padding: '2px 8px',
                fontSize: 12,
                fontFamily: 'system-ui, sans-serif',
                fontWeight: 600,
                border: `1px solid ${isDark ? '#475569' : '#cbd5e1'}`,
                whiteSpace: 'nowrap',
              }}
            >
              {key}
            </kbd>
            <span style={{ fontSize: 13, color: isDark ? '#94a3b8' : '#64748b', marginLeft: 12 }}>
              {description}
            </span>
          </div>
        ))}
      </div>
    </div>
  )
}