Change:
This should not be a valid state: ! It should automatically switch to this: ! is how the SCM Input does it.
I am seeing this state when I am navigating using up/down buttons. Is it expected? ! !
That is probably unexpected, but I will let confirm that.
Yeah, just like the text box. The list doesn't support completely disabling it at the model layer. We can only disable it at the click operation.

Discussion:
static readonly TEMPLATE_ID = 'actionButton'; get templateId(): string { return ActionButtonRenderer.TEMPLATE_ID; } <ins> private actionButtons = new Map<ISCMActionButton, SCMActionButton>(); </ins> constructor( @ICommandService private commandService: ICommandService, @IContextMenuService private contextMenuService: IContextMenuService,

renderElement(node: ITreeNode<ISCMActionButton, FuzzyScore>, index: number, templateData: ActionButtonTemplate, height: number | undefined): void { templateData.disposable.dispose(); <ins> const disposables = new DisposableStore(); const actionButton = node.element; </ins> templateData.actionButton.setButton(node.element.button); <ins> // Remember action button this.actionButtons.set(actionButton, templateData.actionButton); disposables.add({ dispose: () => this.actionButtons.delete(actionButton) }); templateData.disposable = disposables; </ins> } renderCompressedElements(): void { throw new Error('Should never happen since node is incompressible'); } <ins> focusActionButton(actionButton: ISCMActionButton): void { this.actionButtons.get(actionButton)?.focus(); } </ins> disposeElement(node: ITreeNode<ISCMActionButton, FuzzyScore>, index: number, template: ActionButtonTemplate): void { template.disposable.dispose(); }

get viewModel(): ViewModel { return this._viewModel; } private listLabels!: ResourceLabels; private inputRenderer!: InputRenderer; <ins> private actionButtonRenderer!: ActionButtonRenderer; </ins> private readonly disposables = new DisposableStore(); constructor(

this.inputRenderer = this.instantiationService.createInstance(InputRenderer, this.layoutCache, overflowWidgetsDomNode, (input, height) => this.tree.updateElementHeight(input, height)); const delegate = new ListDelegate(this.inputRenderer); <ins> this.actionButtonRenderer = this.instantiationService.createInstance(ActionButtonRenderer); </ins> this.listLabels = this.instantiationService.createInstance(ResourceLabels, { onDidChangeVisibility: this.onDidChangeBodyVisibility }); this._register(this.listLabels);

const renderers: ICompressibleTreeRenderer<any, any, any>[] = [ this.instantiationService.createInstance(RepositoryRenderer, getActionViewItemProvider(this.instantiationService)), this.inputRenderer, <del> this.instantiationService.createInstance(ActionButtonRenderer), </del> <ins> this.actionButtonRenderer, </ins> this.instantiationService.createInstance(ResourceGroupRenderer, getActionViewItemProvider(this.instantiationService)), this._register(this.instantiationService.createInstance(ResourceRenderer, () => this._viewModel, this.listLabels, getActionViewItemProvider(this.instantiationService), actionRunner)) ];

return; } else if (isSCMActionButton(e.element)) { this.scmViewService.focus(e.element.repository); <ins> this.actionButtonRenderer.focusActionButton(e.element); </ins> return; }

this.disposables.value!.add(attachButtonStyler(this.button, this.themeService)); } <ins> focus(): void { this.button?.focus(); } </ins> private clear(): void { this.disposables.value = new DisposableStore(); this.button = undefined;