@@ -59,6 +59,7 @@ function appendFiftInstructions(
5959function InstructionsPage ( ) {
6060 const [ spec , setSpec ] = useState < TvmSpec | null > ( null )
6161 const [ expandedRows , setExpandedRows ] = useState < Record < string , boolean > > ( { } )
62+ const [ anchorInstruction , setAnchorInstruction ] = useState < string | null > ( null )
6263
6364 const stored = loadStoredSettings ( )
6465
@@ -76,10 +77,33 @@ function InstructionsPage() {
7677 setSpec ( tvmSpecData as unknown as TvmSpec )
7778 } , [ ] )
7879
80+ useEffect ( ( ) => {
81+ const handleHashChange = ( ) => {
82+ const hash = window . location . hash . slice ( 1 ) // Remove the '#'
83+ if ( hash && hash !== anchorInstruction ) {
84+ setAnchorInstruction ( hash )
85+ setExpandedRows ( prev => ( {
86+ ...prev ,
87+ [ hash ] : true ,
88+ } ) )
89+ }
90+ }
91+
92+ handleHashChange ( )
93+ window . addEventListener ( "hashchange" , handleHashChange )
94+ return ( ) => window . removeEventListener ( "hashchange" , handleHashChange )
95+ } , [ anchorInstruction ] )
96+
7997 const toggleColumn = ( key : InstructionColumnKey ) => {
8098 setSearchColumns ( prev => ( prev . includes ( key ) ? prev . filter ( k => k !== key ) : [ ...prev , key ] ) )
8199 }
82100
101+ const resetAnchor = ( ) => {
102+ setAnchorInstruction ( null )
103+ window . history . replaceState ( null , "" , window . location . pathname )
104+ setExpandedRows ( { } )
105+ }
106+
83107 const instructions = useMemo ( ( ) => {
84108 return spec ?. instructions ?? ( { } as TvmSpec [ "instructions" ] )
85109 } , [ spec ?. instructions ] )
@@ -162,6 +186,22 @@ function InstructionsPage() {
162186
163187 const filteredInstructions = useMemo ( ( ) => {
164188 const q = query . trim ( ) . toLowerCase ( )
189+
190+ if ( anchorInstruction ) {
191+ const allInstructions = spec ?. instructions ?? { }
192+ if ( allInstructions [ anchorInstruction ] ) {
193+ return { [ anchorInstruction ] : allInstructions [ anchorInstruction ] }
194+ } else {
195+ // Clear anchor if the instruction is not found
196+ setTimeout ( ( ) => {
197+ setAnchorInstruction ( null )
198+ window . history . replaceState ( null , "" , window . location . pathname )
199+ setExpandedRows ( { } )
200+ } , 0 )
201+ return filteredByCategory
202+ }
203+ }
204+
165205 if ( ! q ) return filteredByCategory
166206
167207 const entries = Object . entries ( filteredByCategory )
@@ -183,7 +223,7 @@ function InstructionsPage() {
183223 if ( match ) next [ name ] = instruction
184224 }
185225 return next
186- } , [ query , filteredByCategory , searchColumns ] )
226+ } , [ query , filteredByCategory , searchColumns , anchorInstruction , spec ?. instructions ] )
187227
188228 const sortedInstructions = useMemo ( ( ) => {
189229 const entries = Object . entries ( filteredInstructions )
@@ -252,6 +292,9 @@ function InstructionsPage() {
252292 }
253293
254294 const handleRowClick = ( instructionName : string ) => {
295+ // don't allow collapsing the instruction in anchor mode
296+ if ( anchorInstruction ) return
297+
255298 setExpandedRows ( prev => ( {
256299 ...prev ,
257300 [ instructionName ] : ! prev [ instructionName ] ,
@@ -266,45 +309,57 @@ function InstructionsPage() {
266309
267310 < main className = { styles . appContainer } role = "main" aria-label = "TVM Instructions" >
268311 < div className = { styles . mainContent } >
269- < div className = { styles . toolbar } role = "search" aria-label = "Toolbar" >
270- < SortSelector value = { sortMode } onChange = { setSortMode } />
271-
272- < div className = { styles . searchToolbar } >
273- < SearchColumnsSelector value = { searchColumns } onToggle = { toggleColumn } />
274- < div className = { styles . searchInputContainer } >
275- < SearchInput
276- value = { query }
277- onChange = { setQuery }
278- onSubmit = { ( ) => { } }
279- placeholder = "Search instructions"
280- compact = { true }
281- buttonLabel = "Search"
282- autoFocus = { true }
283- />
312+ { ! anchorInstruction && (
313+ < >
314+ < div className = { styles . toolbar } role = "search" aria-label = "Toolbar" >
315+ < SortSelector value = { sortMode } onChange = { setSortMode } />
316+
317+ < div className = { styles . searchToolbar } >
318+ < SearchColumnsSelector value = { searchColumns } onToggle = { toggleColumn } />
319+ < div className = { styles . searchInputContainer } >
320+ < SearchInput
321+ value = { query }
322+ onChange = { setQuery }
323+ onSubmit = { ( ) => { } }
324+ placeholder = "Search instructions"
325+ compact = { true }
326+ buttonLabel = "Search"
327+ autoFocus = { true }
328+ />
329+ </ div >
330+ </ div >
284331 </ div >
285- </ div >
286- </ div >
287- < div >
288- < CategoryTabs
289- categories = { categories }
290- selected = { selectedCategory }
291- onSelect = { cat => {
292- setSelectedCategory ( cat )
293- setSelectedSubCategory ( "All" )
294- } }
295- />
296- { subCategories . length > 0 && (
297- < div className = { styles . subCategoryAndDocsContainer } >
332+ < div >
298333 < CategoryTabs
299- categories = { subCategories }
300- selected = { selectedSubCategory }
301- onSelect = { setSelectedSubCategory }
302- label = "Subcategory:"
334+ categories = { categories }
335+ selected = { selectedCategory }
336+ onSelect = { cat => {
337+ setSelectedCategory ( cat )
338+ setSelectedSubCategory ( "All" )
339+ } }
303340 />
304- { selectedCategory === "continuation" && < ContinuationsDocsBanner /> }
341+ { subCategories . length > 0 && (
342+ < div className = { styles . subCategoryAndDocsContainer } >
343+ < CategoryTabs
344+ categories = { subCategories }
345+ selected = { selectedSubCategory }
346+ onSelect = { setSelectedSubCategory }
347+ label = "Subcategory:"
348+ />
349+ { selectedCategory === "continuation" && < ContinuationsDocsBanner /> }
350+ </ div >
351+ ) }
305352 </ div >
306- ) }
307- </ div >
353+ </ >
354+ ) }
355+ { anchorInstruction && (
356+ < div className = { styles . anchorIndicator } >
357+ < span > Showing: { anchorInstruction } </ span >
358+ < Button variant = "outline" size = "sm" onClick = { resetAnchor } >
359+ Back to table
360+ </ Button >
361+ </ div >
362+ ) }
308363 < InstructionTable
309364 instructions = { sortedInstructions }
310365 expandedRows = { expandedRows }
0 commit comments