電子冒険:エピソード27:ファイルマネージャキーボード規制


このエピソードは、驚くほどのコラボレーションで作成されましたAmanda Cavallaro .
正統のファイルマネージャのまさにポイントは、彼らが100 %のキーボード使用のために設計されているということです.まだマウスを使用することができますが、それはキーボードの最初の世界です.そして、それはブラウザがどのように動作するかではないので、我々はそれらすべてのものを実装する必要があります.
私は以前のエピソードでは、コードを起動し、いくつかのキーボードショートカットを追加します.

キーボードショートカット


今、最も基本的なキーボードショートカットを追加します.
  • パネルの次の項目に移動します
  • パネルの前の項目に移動します
  • パネル間のタブスイッチ
  • スペースは、現在のアイテムの選択状態を反転し、可能な場合は、次の項目に行く-この方法は非常に簡単にアイテムの束を一度にマークする
  • ブラウザのキーボードイベント


    短い答え-残念ながら、我々はしたい方法.いつ<input> 要素をフォーカスし、キーボードイベントを取得します.しかし、ここで“フォーカシング”のいずれかをしないように、すべてのイベントだけでトップレベルに行くwindow .
    適切な場所にそれらをルーティングするには、いくつかの複雑なイベントルーティングを行う必要があります.幸いにも、Svelteはここで私たちの背中を持っており、どんなコンポーネントもイベントハンドラを<svelte:window> 要素、およびsvelteは正しいことを行います.

    アプリ。Svelteタブ処理


    主要なコンポーネントは、1つのイベントを処理する必要があります.プレスTab どのパネルがアクティブかを切り替えるべきです.
    これには追加が必要です:
    <script>
        let handleKey = (e) => {
        if (e.key === "Tab") {
          if (activePanel === "left") {
            activePanel = "right"
          } else {
            activePanel = "left"
          }
          e.preventDefault()
        }
      }
    </script>
    
    <svelte:window on:keydown={handleKey}/>
    
    注意e.preventDefault() 条件が-タブキーが押された場合にのみ発生します.

    パネル。スベルト


    合計5つのイベントを処理する必要があります.
  • 矢印キー-前の項目に移動
  • 矢印ダウンキー-次の項目に移動
  • スペースキー-フリップの選択、次の項目に移動
  • 左クリック-アクティブパネルをクリックし、項目をクリック
  • 右クリック-アクティブパネルをクリックし、クリックした項目に移動、フリップ選択
  • それらの間にいくつかの重なりがあるので、ヘルパー関数にいくつかのロジックを抽出しました.変更点を以下に示します:
    <script>
      export let position
      export let files
      export let active
      export let onActivate
    
      let focused = files[0]
      let selected = []
      let onclick = (file) => {
        onActivate(position)
        focused = file
      }
      let onrightclick = (file) => {
        onActivate(position)
        focused = file
        flipSelected(file)
      }
      let flipSelected = (file) => {
        if (selected.includes(file)) {
          selected = selected.filter(f => f !== file)
        } else {
          selected = [...selected, file]
        }
      }
      let goUp = () => {
        let i = files.indexOf(focused)
        if (i > 0) {
          focused = files[i - 1]
        }
      }
      let goDown = () => {
        let i = files.indexOf(focused)
        if (i < files.length - 1) {
          focused = files[i + 1]
        }
      }
      let handleKey = (e) => {
        if (!active) {
          return
        }
        if (e.key === "ArrowDown") {
          e.preventDefault()
          goDown()
        }
        if (e.key === "ArrowUp") {
          e.preventDefault()
          goUp()
        }
        if (e.key === " ") {
          e.preventDefault()
          flipSelected(focused)
          goDown()
        }
      }
    </script>
    
    <svelte:window on:keydown={handleKey}/>
    
    もう一つの論理があり、Svelteはここで私たちを助けてくれます.window すべてのキープレス、および登録されたすべてのコンポーネントを受け取りますon:keydown を参照してください.これはPanel sはあらゆるキーを送りますPanel 'それが活発であるならば、チェックして、イベントを扱うだけであるs責任.
    マウスイベントについては、どのパネルがクリックされたかを知っているので、このようなチェックは行いませんPanel を返します.
    ロジックは、同じフォルダ内の同じ名前を持つ2つのファイルを持つことができないように、リスト上の各項目は、常にファイルの真の、一意であると仮定する実装されます.しかし、他の種類のアイテムに対してこのコードを適用しようとすると、フォーカスされない/選択された位置を保存する必要があります.
    また、矢印やタブのような特別なキーについては、我々は処理する必要がありますkeydown ないkeypress イベント.keypress 文字、数字、およびスペースのような通常のキーをトリガーするだけです.

    結果


    静けさのモックアップと同様に、まだ見ています

    我々は将来のエピソードで我々のアプリに取り組んでいきますが、最初に私は小さな迂回何か全く別のを取るつもりです.
    いつものように.all the code for the episode is here .