github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/web/src/ResourceSelectionContext.tsx (about) 1 import { 2 createContext, 3 PropsWithChildren, 4 useContext, 5 useMemo, 6 useState, 7 } from "react" 8 9 /** 10 * The ResourceSelection state keeps track of what resources are selected for bulk actions to be performed on them. 11 */ 12 13 export type ResourceSelectionContext = { 14 selected: Set<string> 15 isSelected: (resourceName: string) => boolean 16 select: (...resourceNames: string[]) => void 17 deselect: (...resourceNames: string[]) => void 18 clearSelections: () => void 19 } 20 21 const ResourceSelectionContext = createContext<ResourceSelectionContext>({ 22 selected: new Set(), 23 isSelected: (_resourceName: string) => { 24 console.warn("Resource selections context is not set.") 25 return false 26 }, 27 select: (..._resourceNames: string[]) => { 28 console.warn("Resource selections context is not set.") 29 }, 30 deselect: (..._resourceNames: string[]) => { 31 console.warn("Resource selections context is not set.") 32 }, 33 clearSelections: () => { 34 console.warn("Resource selections context is not set.") 35 }, 36 }) 37 38 ResourceSelectionContext.displayName = "ResourceSelectionContext" 39 40 export function useResourceSelection(): ResourceSelectionContext { 41 return useContext(ResourceSelectionContext) 42 } 43 44 export function ResourceSelectionProvider( 45 props: PropsWithChildren<{ initialValuesForTesting?: string[] }> 46 ) { 47 const selections = new Set(props.initialValuesForTesting) || new Set() 48 const [selectedResources, setSelectedResources] = useState(selections) 49 50 const contextValue: ResourceSelectionContext = useMemo(() => { 51 function isSelected(resourceName: string) { 52 return selectedResources.has(resourceName) 53 } 54 55 function select(...resourceNames: string[]) { 56 const newSelections = new Set<string>(selectedResources) 57 resourceNames.forEach((name) => newSelections.add(name)) 58 return setSelectedResources(newSelections) 59 } 60 61 function deselect(...resourceNames: string[]) { 62 const newSelections = new Set<string>(selectedResources) 63 resourceNames.forEach((name) => newSelections.delete(name)) 64 return setSelectedResources(newSelections) 65 } 66 67 function clearSelections() { 68 setSelectedResources(new Set()) 69 } 70 return { 71 selected: selectedResources, 72 isSelected, 73 select, 74 deselect, 75 clearSelections, 76 } 77 }, [selectedResources, setSelectedResources]) 78 79 return ( 80 <ResourceSelectionContext.Provider value={contextValue}> 81 {props.children} 82 </ResourceSelectionContext.Provider> 83 ) 84 }