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 }