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

     1  import React, { Component } from "react"
     2  import { AnalyticsAction, incr } from "./analytics"
     3  import { ResourceNav, useResourceNav } from "./ResourceNav"
     4  import { isTargetEditable } from "./shortcut"
     5  import SidebarItem from "./SidebarItem"
     6  import { ResourceName, ResourceView } from "./types"
     7  
     8  type Props = {
     9    items: SidebarItem[]
    10    selected: string
    11    resourceNav: ResourceNav
    12    resourceView: ResourceView
    13    onStartBuild: () => void
    14  }
    15  
    16  /**
    17   * Sets up keyboard shortcuts that depend on the state of the sidebar.
    18   */
    19  class SidebarKeyboardShortcuts 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)) {
    35        return
    36      }
    37  
    38      if (e.shiftKey || e.altKey || e.isComposing) {
    39        return
    40      }
    41  
    42      let items = this.props.items
    43      let selected = this.props.selected || ResourceName.all
    44      switch (e.key) {
    45        case "j":
    46        case "k":
    47          // An array of sidebar items, plus one at the beginning for 'All'
    48          let names = [ResourceName.all as string].concat(
    49            items.map((item) => item.name)
    50          )
    51          let index = names.indexOf(selected)
    52          let dir = e.key === "j" ? 1 : -1
    53          let targetIndex = index + dir
    54          if (targetIndex < 0 || targetIndex >= names.length) {
    55            return
    56          }
    57  
    58          let name = names[targetIndex]
    59          this.props.resourceNav.openResource(name)
    60          e.preventDefault()
    61          break
    62  
    63        case "r":
    64          if (e.metaKey || e.ctrlKey) {
    65            return
    66          }
    67          let item = items.find((item) => item.name == selected)
    68          this.props.onStartBuild()
    69          incr("ui.web.triggerResource", {
    70            action: AnalyticsAction.Shortcut,
    71            target: item?.targetType || "",
    72          })
    73          e.preventDefault()
    74          break
    75      }
    76    }
    77  
    78    render() {
    79      return <span></span>
    80    }
    81  }
    82  
    83  type PublicProps = {
    84    items: SidebarItem[]
    85    selected: string
    86    onStartBuild: () => void
    87    resourceView: ResourceView
    88  }
    89  
    90  export default function (props: PublicProps) {
    91    let resourceNav = useResourceNav()
    92    return <SidebarKeyboardShortcuts {...props} resourceNav={resourceNav} />
    93  }