github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/web/src/OverviewTableKeyboardShortcuts.tsx (about)

     1  import React, { Component } from "react"
     2  import { RowValues } from "./OverviewTableColumns"
     3  import {
     4    ResourceSelectionContext,
     5    useResourceSelection,
     6  } from "./ResourceSelectionContext"
     7  import { isTargetEditable } from "./shortcut"
     8  
     9  type Props = {
    10    rows: RowValues[]
    11    focused: string
    12    setFocused: (focused: string) => void
    13    selection: ResourceSelectionContext
    14  }
    15  
    16  /**
    17   * Sets up keyboard shortcuts that depend on the state of the sidebar.
    18   */
    19  class Shortcuts extends Component<Props> {
    20    constructor(props: Props) {
    21      super(props)
    22      this.onKeydown = this.onKeydown.bind(this)
    23    }
    24  
    25    componentDidMount() {
    26      document.body.addEventListener("keydown", this.onKeydown)
    27    }
    28  
    29    componentWillUnmount() {
    30      document.body.removeEventListener("keydown", this.onKeydown)
    31    }
    32  
    33    onKeydown(e: KeyboardEvent) {
    34      if (isTargetEditable(e) || e.shiftKey || e.altKey || e.isComposing) {
    35        return
    36      }
    37  
    38      let items = this.props.rows
    39      let focused = this.props.focused
    40      let dir = 0
    41      switch (e.key) {
    42        case "Down":
    43        case "ArrowDown":
    44        case "j":
    45          dir = 1
    46          break
    47  
    48        case "Up":
    49        case "ArrowUp":
    50        case "k":
    51          dir = -1
    52          break
    53  
    54        case "x":
    55          if (e.metaKey || e.ctrlKey) {
    56            return
    57          }
    58          let item = items.find((item) => item.name == focused)
    59          if (item && item.selectable) {
    60            let selection = this.props.selection
    61            if (selection.isSelected(item.name)) {
    62              this.props.selection.deselect(item.name)
    63            } else {
    64              this.props.selection.select(item.name)
    65            }
    66            e.preventDefault()
    67          }
    68          break
    69      }
    70  
    71      if (dir != 0) {
    72        // Select up and down the list.
    73        let names = items.map((item) => item.name)
    74        let index = names.indexOf(focused)
    75        let targetIndex = 0
    76        if (index != -1) {
    77          let dir = e.key === "j" ? 1 : -1
    78          targetIndex = index + dir
    79        }
    80  
    81        if (targetIndex < 0 || targetIndex >= names.length) {
    82          return
    83        }
    84  
    85        let name = names[targetIndex]
    86        this.props.setFocused(name)
    87        e.preventDefault()
    88        return
    89      }
    90    }
    91  
    92    render() {
    93      return <span></span>
    94    }
    95  }
    96  
    97  type PublicProps = {
    98    rows: RowValues[]
    99    focused: string
   100    setFocused: (focused: string) => void
   101  }
   102  
   103  export function OverviewTableKeyboardShortcuts(props: PublicProps) {
   104    let selection = useResourceSelection()
   105    return <Shortcuts {...props} selection={selection} />
   106  }