From 8a5d56ec6e6737b37cdaff62429535e2258912e1 Mon Sep 17 00:00:00 2001 From: scottdurow Date: Thu, 1 Dec 2022 10:55:26 -0800 Subject: [PATCH] fix:#7 accessible action buttons --- .../PowerDragDrop/ControlManifest.Input.xml | 2 +- code-component/PowerDragDrop/index.ts | 75 +++++++++++++------ 2 files changed, 52 insertions(+), 25 deletions(-) diff --git a/code-component/PowerDragDrop/ControlManifest.Input.xml b/code-component/PowerDragDrop/ControlManifest.Input.xml index 9b452dd..b2a6f9e 100644 --- a/code-component/PowerDragDrop/ControlManifest.Input.xml +++ b/code-component/PowerDragDrop/ControlManifest.Input.xml @@ -1,6 +1,6 @@  - + diff --git a/code-component/PowerDragDrop/index.ts b/code-component/PowerDragDrop/index.ts index f3212e7..37acbbb 100644 --- a/code-component/PowerDragDrop/index.ts +++ b/code-component/PowerDragDrop/index.ts @@ -30,6 +30,7 @@ interface RegisteredZone { zoneId: string; maximumItems: number | undefined; sortable: Sortable; + onActionClick: (ev: MouseEvent) => void; } const defaultSortableOptions: Sortable.Options = { @@ -321,21 +322,26 @@ export class PowerDragDrop implements ComponentFramework.StandardControl { + this.actionClick(ev, zoneElement); + }, + sortable: sortable, }; + this.zonesRegistered[zoneId] = zoneRegistration; + zoneElement.addEventListener('click', zoneRegistration.onActionClick); } }); @@ -377,7 +383,12 @@ export class PowerDragDrop implements ComponentFramework.StandardControl { - const actionItemId = event.item.getAttribute(RECORD_ID_ATTRIBUTE); - const actionName = this.getActionFromClass(event.target); - if (actionItemId && actionName) { - this.raiseOnActionScheduled = true; - // Remove the action specifier - this.actionName = actionName.replace(CSS_STYLE_CLASSES.ActionClassPrefix, ''); - this.actionItemId = actionItemId; - this.notifyOutputChanged(); - } - }; - private removeSpaces(input: string) { return input.replace(/\s/gi, ''); } @@ -493,4 +492,32 @@ export class PowerDragDrop implements ComponentFramework.StandardControl { + // For accessibility, action elements raise the OnAction event here + // rather than the onFilter event which only fires for touch events + if (ev.target && (ev.target as HTMLElement).className) { + const actionName = this.getActionFromClass(ev.target as HTMLElement); + // Actions have a class prefixed with action- + if (actionName) { + // Find the closest sortable item using the item class identifier + const element = Sortable.utils.closest( + ev.target as HTMLElement, + '.' + CSS_STYLE_CLASSES.Item, + zoneElement, + ); + if (element) { + // Get the item id from the data attribute + const actionItemId = element.getAttribute(RECORD_ID_ATTRIBUTE); + if (actionItemId) { + this.raiseOnActionScheduled = true; + // Remove the action specifier and raise the event + this.actionName = actionName.replace(CSS_STYLE_CLASSES.ActionClassPrefix, ''); + this.actionItemId = actionItemId; + this.notifyOutputChanged(); + } + } + } + } + }; }