github.com/tilt-dev/tilt@v0.36.0/web/src/SidebarKeyboardShortcuts.tsx (about)

     1  import React, { Component } from "react"
     2  import { ResourceNav, useResourceNav } from "./ResourceNav"
     3  import { isTargetEditable } from "./shortcut"
     4  import SidebarItem from "./SidebarItem"
     5  import { ResourceName, ResourceView } from "./types"
     6  
     7  type Props = {
     8    items: SidebarItem[]
     9    selected: string
    10    resourceNav: ResourceNav
    11    resourceView: ResourceView
    12    onStartBuild: () => void
    13  }
    14  
    15  /**
    16   * Sets up keyboard shortcuts that depend on the state of the sidebar.
    17   */
    18  class SidebarKeyboardShortcuts extends Component<Props> {
    19    constructor(props: Props) {
    20      super(props)
    21      this.onKeydown = this.onKeydown.bind(this)
    22    }
    23  
    24    componentDidMount() {
    25      document.body.addEventListener("keydown", this.onKeydown)
    26    }
    27  
    28    componentWillUnmount() {
    29      document.body.removeEventListener("keydown", this.onKeydown)
    30    }
    31  
    32    onKeydown(e: KeyboardEvent) {
    33      if (isTargetEditable(e)) {
    34        return
    35      }
    36  
    37      if (e.shiftKey || e.altKey || e.isComposing) {
    38        return
    39      }
    40  
    41      let items = this.props.items
    42      let selected = this.props.selected || ResourceName.all
    43      switch (e.key) {
    44        case "j":
    45        case "k":
    46          // An array of sidebar items, plus one at the beginning for 'All'
    47          let names = [ResourceName.all as string].concat(
    48            items.map((item) => item.name)
    49          )
    50          let index = names.indexOf(selected)
    51          let dir = e.key === "j" ? 1 : -1
    52          let targetIndex = index + dir
    53          if (targetIndex < 0 || targetIndex >= names.length) {
    54            return
    55          }
    56  
    57          let name = names[targetIndex]
    58          this.props.resourceNav.openResource(name)
    59          e.preventDefault()
    60          break
    61  
    62        case "r":
    63          if (e.metaKey || e.ctrlKey) {
    64            return
    65          }
    66          let item = items.find((item) => item.name == selected)
    67          this.props.onStartBuild()
    68          e.preventDefault()
    69          break
    70      }
    71    }
    72  
    73    render() {
    74      return <span></span>
    75    }
    76  }
    77  
    78  type PublicProps = {
    79    items: SidebarItem[]
    80    selected: string
    81    onStartBuild: () => void
    82    resourceView: ResourceView
    83  }
    84  
    85  export default function (props: PublicProps) {
    86    let resourceNav = useResourceNav()
    87    return <SidebarKeyboardShortcuts {...props} resourceNav={resourceNav} />
    88  }