55 VSCodeProgressRing ,
66} from "@vscode/webview-ui-toolkit/react" ;
77import * as React from "react" ;
8- import { useCallback } from "react" ;
8+ import { forwardRef , useCallback , useEffect , useRef } from "react" ;
99import { styled } from "styled-components" ;
1010import { vscode } from "../vscode-api" ;
1111
@@ -47,112 +47,150 @@ const ProgressRing = styled(VSCodeProgressRing)`
4747 margin-left: auto;
4848` ;
4949
50+ const DataGridRow = styled ( VSCodeDataGridRow ) < { focused ?: boolean } > `
51+ outline: ${ ( props ) =>
52+ props . focused ? "1px solid var(--vscode-focusBorder)" : "none" } ;
53+ ` ;
54+
5055export type MethodRowProps = {
5156 method : Method ;
5257 methodCanBeModeled : boolean ;
5358 modeledMethod : ModeledMethod | undefined ;
5459 methodIsUnsaved : boolean ;
5560 modelingInProgress : boolean ;
5661 mode : Mode ;
62+ revealedMethodSignature : string | null ;
5763 onChange : ( modeledMethod : ModeledMethod ) => void ;
5864} ;
5965
6066export const MethodRow = ( props : MethodRowProps ) => {
61- const { methodCanBeModeled } = props ;
67+ const { method, methodCanBeModeled, revealedMethodSignature } = props ;
68+
69+ const ref = useRef < HTMLElement > ( ) ;
70+
71+ useEffect ( ( ) => {
72+ if ( method . signature === revealedMethodSignature ) {
73+ ref . current ?. scrollIntoView ( {
74+ behavior : "smooth" ,
75+ block : "center" ,
76+ } ) ;
77+ }
78+ } , [ method , revealedMethodSignature ] ) ;
6279
6380 if ( methodCanBeModeled ) {
64- return < ModelableMethodRow { ...props } /> ;
81+ return < ModelableMethodRow { ...props } ref = { ref } /> ;
6582 } else {
66- return < UnmodelableMethodRow { ...props } /> ;
83+ return < UnmodelableMethodRow { ...props } ref = { ref } /> ;
6784 }
6885} ;
6986
70- function ModelableMethodRow ( props : MethodRowProps ) {
71- const { method, modeledMethod, methodIsUnsaved, mode, onChange } = props ;
72-
73- const jumpToUsage = useCallback (
74- ( ) => sendJumpToUsageMessage ( method ) ,
75- [ method ] ,
76- ) ;
77-
78- const modelingStatus = getModelingStatus ( modeledMethod , methodIsUnsaved ) ;
79-
80- return (
81- < VSCodeDataGridRow data-testid = "modelable-method-row" >
82- < ApiOrMethodCell gridColumn = { 1 } >
83- < ModelingStatusIndicator status = { modelingStatus } />
84- < MethodClassifications method = { method } />
85- < MethodName { ...props . method } />
86- { mode === Mode . Application && (
87- < UsagesButton onClick = { jumpToUsage } >
88- { method . usages . length }
89- </ UsagesButton >
87+ const ModelableMethodRow = forwardRef < HTMLElement | undefined , MethodRowProps > (
88+ ( props , ref ) => {
89+ const {
90+ method,
91+ modeledMethod,
92+ methodIsUnsaved,
93+ mode,
94+ revealedMethodSignature,
95+ onChange,
96+ } = props ;
97+
98+ const jumpToUsage = useCallback (
99+ ( ) => sendJumpToUsageMessage ( method ) ,
100+ [ method ] ,
101+ ) ;
102+
103+ const modelingStatus = getModelingStatus ( modeledMethod , methodIsUnsaved ) ;
104+
105+ return (
106+ < DataGridRow
107+ data-testid = "modelable-method-row"
108+ ref = { ref }
109+ focused = { revealedMethodSignature === method . signature }
110+ >
111+ < ApiOrMethodCell gridColumn = { 1 } >
112+ < ModelingStatusIndicator status = { modelingStatus } />
113+ < MethodClassifications method = { method } />
114+ < MethodName { ...props . method } />
115+ { mode === Mode . Application && (
116+ < UsagesButton onClick = { jumpToUsage } >
117+ { method . usages . length }
118+ </ UsagesButton >
119+ ) }
120+ < ViewLink onClick = { jumpToUsage } > View</ ViewLink >
121+ { props . modelingInProgress && < ProgressRing /> }
122+ </ ApiOrMethodCell >
123+ { props . modelingInProgress && (
124+ < >
125+ < VSCodeDataGridCell gridColumn = { 2 } >
126+ < InProgressDropdown />
127+ </ VSCodeDataGridCell >
128+ < VSCodeDataGridCell gridColumn = { 3 } >
129+ < InProgressDropdown />
130+ </ VSCodeDataGridCell >
131+ < VSCodeDataGridCell gridColumn = { 4 } >
132+ < InProgressDropdown />
133+ </ VSCodeDataGridCell >
134+ < VSCodeDataGridCell gridColumn = { 5 } >
135+ < InProgressDropdown />
136+ </ VSCodeDataGridCell >
137+ </ >
90138 ) }
91- < ViewLink onClick = { jumpToUsage } > View</ ViewLink >
92- { props . modelingInProgress && < ProgressRing /> }
93- </ ApiOrMethodCell >
94- { props . modelingInProgress && (
95- < >
96- < VSCodeDataGridCell gridColumn = { 2 } >
97- < InProgressDropdown />
98- </ VSCodeDataGridCell >
99- < VSCodeDataGridCell gridColumn = { 3 } >
100- < InProgressDropdown />
101- </ VSCodeDataGridCell >
102- < VSCodeDataGridCell gridColumn = { 4 } >
103- < InProgressDropdown />
104- </ VSCodeDataGridCell >
105- < VSCodeDataGridCell gridColumn = { 5 } >
106- < InProgressDropdown />
107- </ VSCodeDataGridCell >
108- </ >
109- ) }
110- { ! props . modelingInProgress && (
111- < >
112- < VSCodeDataGridCell gridColumn = { 2 } >
113- < ModelTypeDropdown
114- method = { method }
115- modeledMethod = { modeledMethod }
116- onChange = { onChange }
117- />
118- </ VSCodeDataGridCell >
119- < VSCodeDataGridCell gridColumn = { 3 } >
120- < ModelInputDropdown
121- method = { method }
122- modeledMethod = { modeledMethod }
123- onChange = { onChange }
124- />
125- </ VSCodeDataGridCell >
126- < VSCodeDataGridCell gridColumn = { 4 } >
127- < ModelOutputDropdown
128- method = { method }
129- modeledMethod = { modeledMethod }
130- onChange = { onChange }
131- />
132- </ VSCodeDataGridCell >
133- < VSCodeDataGridCell gridColumn = { 5 } >
134- < ModelKindDropdown
135- method = { method }
136- modeledMethod = { modeledMethod }
137- onChange = { onChange }
138- />
139- </ VSCodeDataGridCell >
140- </ >
141- ) }
142- </ VSCodeDataGridRow >
143- ) ;
144- }
145-
146- function UnmodelableMethodRow ( props : MethodRowProps ) {
147- const { method, mode } = props ;
139+ { ! props . modelingInProgress && (
140+ < >
141+ < VSCodeDataGridCell gridColumn = { 2 } >
142+ < ModelTypeDropdown
143+ method = { method }
144+ modeledMethod = { modeledMethod }
145+ onChange = { onChange }
146+ />
147+ </ VSCodeDataGridCell >
148+ < VSCodeDataGridCell gridColumn = { 3 } >
149+ < ModelInputDropdown
150+ method = { method }
151+ modeledMethod = { modeledMethod }
152+ onChange = { onChange }
153+ />
154+ </ VSCodeDataGridCell >
155+ < VSCodeDataGridCell gridColumn = { 4 } >
156+ < ModelOutputDropdown
157+ method = { method }
158+ modeledMethod = { modeledMethod }
159+ onChange = { onChange }
160+ />
161+ </ VSCodeDataGridCell >
162+ < VSCodeDataGridCell gridColumn = { 5 } >
163+ < ModelKindDropdown
164+ method = { method }
165+ modeledMethod = { modeledMethod }
166+ onChange = { onChange }
167+ />
168+ </ VSCodeDataGridCell >
169+ </ >
170+ ) }
171+ </ DataGridRow >
172+ ) ;
173+ } ,
174+ ) ;
175+ ModelableMethodRow . displayName = "ModelableMethodRow" ;
176+
177+ const UnmodelableMethodRow = forwardRef <
178+ HTMLElement | undefined ,
179+ MethodRowProps
180+ > ( ( props , ref ) => {
181+ const { method, mode, revealedMethodSignature } = props ;
148182
149183 const jumpToUsage = useCallback (
150184 ( ) => sendJumpToUsageMessage ( method ) ,
151185 [ method ] ,
152186 ) ;
153187
154188 return (
155- < VSCodeDataGridRow data-testid = "unmodelable-method-row" >
189+ < DataGridRow
190+ data-testid = "unmodelable-method-row"
191+ ref = { ref }
192+ focused = { revealedMethodSignature === method . signature }
193+ >
156194 < ApiOrMethodCell gridColumn = { 1 } >
157195 < ModelingStatusIndicator status = "saved" />
158196 < MethodName { ...props . method } />
@@ -167,9 +205,10 @@ function UnmodelableMethodRow(props: MethodRowProps) {
167205 < VSCodeDataGridCell gridColumn = "span 4" >
168206 Method already modeled
169207 </ VSCodeDataGridCell >
170- </ VSCodeDataGridRow >
208+ </ DataGridRow >
171209 ) ;
172- }
210+ } ) ;
211+ UnmodelableMethodRow . displayName = "UnmodelableMethodRow" ;
173212
174213function sendJumpToUsageMessage ( method : Method ) {
175214 vscode . postMessage ( {
0 commit comments