diff --git a/source/nodejs/adaptivecards-controls/src/popupmenu.ts b/source/nodejs/adaptivecards-controls/src/popupmenu.ts index 4eef2b54eb..80dcbad68d 100644 --- a/source/nodejs/adaptivecards-controls/src/popupmenu.ts +++ b/source/nodejs/adaptivecards-controls/src/popupmenu.ts @@ -14,6 +14,12 @@ export class PopupMenu extends PopupControl { super(); } + focus() { + if (this._renderedItems.length >= 1) { + this._renderedItems[0].focus(); + } + } + protected renderContent(): HTMLElement { var element = document.createElement("div"); element.className = "ms-ctrl ms-popup"; diff --git a/source/nodejs/adaptivecards-designer/src/adaptivecards-designer.css b/source/nodejs/adaptivecards-designer/src/adaptivecards-designer.css index 660d6d6bb2..8628b38197 100644 --- a/source/nodejs/adaptivecards-designer/src/adaptivecards-designer.css +++ b/source/nodejs/adaptivecards-designer/src/adaptivecards-designer.css @@ -776,7 +776,6 @@ pointer-events: all !important; height: 20px; border-radius: 0; - outline: none; } .acd-peerButton.fixedWidth { diff --git a/source/nodejs/adaptivecards-designer/src/card-designer-surface.ts b/source/nodejs/adaptivecards-designer/src/card-designer-surface.ts index 4898490f0e..fe801cef8f 100644 --- a/source/nodejs/adaptivecards-designer/src/card-designer-surface.ts +++ b/source/nodejs/adaptivecards-designer/src/card-designer-surface.ts @@ -166,9 +166,12 @@ class DragHandle extends DraggableElement { let element = document.createElement("div"); element.classList.add("acd-peerButton", "acd-peerButton-icon", "fixedWidth", "circular", "acd-icon-drag"); element.title = "Drag to move this element"; + element.setAttribute("aria-label", "Drag to move this element"); + element.setAttribute("role", "button"); element.style.visibility = "hidden"; element.style.position = "absolute"; element.style.zIndex = "500"; + element.tabIndex = 0; return element; } @@ -227,6 +230,24 @@ export class CardDesignerSurface { this._dragHandle.renderedElement.style.visibility = this._selectedPeer.isDraggable() ? "visible" : "hidden"; this._removeCommandElement.style.visibility = this._selectedPeer.canBeRemoved() ? "visible" : "hidden"; this._peerCommandsHostElement.style.visibility = this._peerCommandsHostElement.childElementCount > 0 ? "visible" : "hidden"; + + // Remove from tree + if (this._designerSurface.contains(this._dragHandle.renderedElement)) { + this._designerSurface.removeChild(this._dragHandle.renderedElement); + } + + if (this._designerSurface.contains(this._removeCommandElement)) { + this._designerSurface.removeChild(this._removeCommandElement); + } + + if (this._designerSurface.contains(this._peerCommandsHostElement)) { + this._designerSurface.removeChild(this._peerCommandsHostElement); + } + + // Insert to the correct location + this._selectedPeer.renderedElement.after(this._dragHandle.renderedElement); + this._dragHandle.renderedElement.after(this._removeCommandElement); + this._removeCommandElement.after(this._peerCommandsHostElement); } else { this._dragHandle.renderedElement.style.visibility = "hidden"; @@ -791,12 +812,20 @@ export class CardDesignerSurface { this._removeCommandElement = document.createElement("div"); this._removeCommandElement.classList.add("acd-peerButton", "acd-peerButton-icon", "fixedWidth", "circular", "acd-icon-remove"); this._removeCommandElement.title = "Remove"; + this._removeCommandElement.setAttribute("aria-label", "Remove"); + this._removeCommandElement.setAttribute("role", "button"); this._removeCommandElement.style.visibility = "hidden"; this._removeCommandElement.style.position = "absolute"; this._removeCommandElement.style.zIndex = "500"; + this._removeCommandElement.tabIndex = 0; this._removeCommandElement.onclick = (e) => { this.removeSelected(); } + this._removeCommandElement.onkeyup = (e: KeyboardEvent) => { + if (e.key === Constants.keys.enter) { + this.removeSelected(); + } + }; this._dragHandle = new DragHandle(); this._dragHandle.onStartDrag = (sender) => { @@ -813,10 +842,6 @@ export class CardDesignerSurface { this._peerCommandsHostElement.style.zIndex = "500"; this._peerCommandsHostElement.style.pointerEvents = "none"; - this._designerSurface.appendChild(this._dragHandle.renderedElement); - this._designerSurface.appendChild(this._removeCommandElement); - this._designerSurface.appendChild(this._peerCommandsHostElement); - this.updateLayout(); // If we have a persistent selected peer, select the peer diff --git a/source/nodejs/adaptivecards-designer/src/designer-peers.ts b/source/nodejs/adaptivecards-designer/src/designer-peers.ts index 77a911bd03..bf386608b5 100644 --- a/source/nodejs/adaptivecards-designer/src/designer-peers.ts +++ b/source/nodejs/adaptivecards-designer/src/designer-peers.ts @@ -1257,6 +1257,16 @@ export abstract class DesignerPeer extends DraggableElement { this.renderedElement.style.left = clientRect.left + "px"; this.renderedElement.style.top = clientRect.top + "px"; } + + this.updateAriaProperties(); + } + + protected updateAriaProperties() { + if (this._children.length === 0 && this.getCardObject() instanceof Adaptive.CardElementContainer) { + this.renderedElement.setAttribute("aria-label", "Empty " + this.getCardObject().getJsonTypeName()); + } else { + this.renderedElement.setAttribute("aria-label", this.getCardObject().getJsonTypeName()); + } } protected createInplaceEditor(): DesignerPeerInplaceEditor { @@ -2170,6 +2180,7 @@ export class AdaptiveCardPeer extends TypedCardElementPeer