You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by bo...@apache.org on 2023/11/16 13:33:17 UTC

(myfaces-tobago) branch main updated: feat(sheet): custom event support for sheet row selection (#4408)

This is an automated email from the ASF dual-hosted git repository.

bommel pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/myfaces-tobago.git


The following commit(s) were added to refs/heads/main by this push:
     new 653eb4fa32 feat(sheet): custom event support for sheet row selection (#4408)
653eb4fa32 is described below

commit 653eb4fa322427c5617b2018b1e95148afd445ca
Author: Bernd Bohmann <bo...@apache.org>
AuthorDate: Thu Nov 16 14:33:11 2023 +0100

    feat(sheet): custom event support for sheet row selection (#4408)
    
    issue: TOBAGO-2239
---
 .../myfaces/tobago/component/ClientBehaviors.java  | 55 +++++++++++++++-------
 .../myfaces/tobago/facelets/EventHandler.java      |  2 +-
 .../renderer/TobagoClientBehaviorRenderer.java     |  2 +-
 .../taglib/component/SheetTagDeclaration.java      |  3 +-
 .../myfaces/tobago/renderkit/RendererBase.java     |  2 +-
 .../apache/myfaces/tobago/util/EnumUnitTest.java   |  6 ++-
 .../tobago/example/demo/SheetController.java       |  8 ++++
 .../25-selection/Sheet_Selectionchange.xhtml       | 51 ++++++++++++++++++++
 .../tobago-theme-standard/src/main/js/tobago.js    |  6 +--
 .../src/main/js/tobago.js.map                      |  2 +-
 .../src/main/ts/tobago-client-behaviors.ts         | 37 +++++++++++++++
 .../src/main/ts/tobago-sheet.ts                    | 18 ++++++-
 12 files changed, 165 insertions(+), 27 deletions(-)

diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/component/ClientBehaviors.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/component/ClientBehaviors.java
index ef47f2c572..7503936ec3 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/component/ClientBehaviors.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/component/ClientBehaviors.java
@@ -21,23 +21,43 @@ package org.apache.myfaces.tobago.component;
 
 public enum ClientBehaviors {
 
-  action, // pure JSF (not a JavaScript event
-  blur,
-  change,
-  click,
-  complete,
-  dblclick,
-  focus,
-  keydown,
-  keypress,
-  keyup,
-  input,
-  load,
-  mouseover,
-  mouseout,
-  reload, // tbd - may be called timeout?
-  resize,
-  suggest; // tbd
+  action("action"), // pure JSF (not a JavaScript event
+  blur("blur"),
+  change("change"),
+  click("click"),
+  complete("complete"),
+  dblclick("dblclick"),
+  focus("focus"),
+  keydown("keydown"),
+  keypress("keypress"),
+  keyup("keyup"),
+  input("input"),
+  load("load"),
+  mouseover("mouseover"),
+  mouseout("mouseout"),
+  reload("reload"), // tbd - may be called timeout?
+  resize("resize"),
+  suggest("suggest"),
+  rowSelectionChange("tobago.sheet.rowSelectionChange");
+
+  private final String jsEvent;
+
+  ClientBehaviors(final String value) {
+    this.jsEvent = value;
+  }
+
+  public String getJsEvent() {
+    return jsEvent;
+  }
+
+  public static ClientBehaviors getEnum(String value) {
+    for (ClientBehaviors clientBehavior : ClientBehaviors.values()) {
+      if (clientBehavior.getJsEvent() != null && clientBehavior.getJsEvent().equals(value)) {
+        return clientBehavior;
+      }
+    }
+    return ClientBehaviors.valueOf(value);
+  }
 
   public static final String ACTION = "action";
   public static final String BLUR = "blur";
@@ -56,5 +76,6 @@ public enum ClientBehaviors {
   public static final String RELOAD = "reload"; // tbd - may be called timeout?
   public static final String RESIZE = "resize";
   public static final String SUGGEST = "suggest"; // tbd
+  public static final String ROW_SELECTION_CHANGE = "tobago.sheet.rowSelectionChange";
 
 }
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/facelets/EventHandler.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/facelets/EventHandler.java
index 871b71ec50..1bfa2fec55 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/facelets/EventHandler.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/facelets/EventHandler.java
@@ -173,7 +173,7 @@ public class EventHandler extends TobagoComponentHandler implements BehaviorHold
     final AbstractUIEvent uiEvent = (AbstractUIEvent) component;
     if (uiEvent.getEvent() == null) {
       final ClientBehaviorHolder holder = (ClientBehaviorHolder) parent;
-      uiEvent.setEvent(ClientBehaviors.valueOf(holder.getDefaultEventName()));
+      uiEvent.setEvent(ClientBehaviors.getEnum(holder.getDefaultEventName()));
     }
   }
 
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TobagoClientBehaviorRenderer.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TobagoClientBehaviorRenderer.java
index f3490890ca..6820a0df5f 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TobagoClientBehaviorRenderer.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TobagoClientBehaviorRenderer.java
@@ -65,7 +65,7 @@ public class TobagoClientBehaviorRenderer extends jakarta.faces.render.ClientBeh
 
     final FacesContext facesContext = behaviorContext.getFacesContext();
     final UIComponent uiComponent = behaviorContext.getComponent();
-    final ClientBehaviors eventName = ClientBehaviors.valueOf(behaviorContext.getEventName());
+    final ClientBehaviors eventName = ClientBehaviors.getEnum(behaviorContext.getEventName());
 
     //// TBD: is this nice? May be implemented with a JSF behavior?
     Collapse collapse = createCollapsible(facesContext, uiComponent);
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SheetTagDeclaration.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SheetTagDeclaration.java
index 7f30da6e91..74cbb8de76 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SheetTagDeclaration.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/SheetTagDeclaration.java
@@ -62,7 +62,8 @@ import jakarta.faces.component.UIData;
     behaviors = {
         @Behavior(
             name = ClientBehaviors.RELOAD, // XXX replace by click
-            isDefault = true)
+            isDefault = true),
+        @Behavior(name = ClientBehaviors.ROW_SELECTION_CHANGE)
     },
     markups = {
         @Markup(
diff --git a/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/RendererBase.java b/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/RendererBase.java
index 4f9ec75316..968028ccc0 100644
--- a/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/RendererBase.java
+++ b/tobago-core/src/main/java/org/apache/myfaces/tobago/renderkit/RendererBase.java
@@ -256,7 +256,7 @@ public abstract class RendererBase<T extends UIComponent> extends Renderer {
       final TobagoResponseWriter writer, final ClientBehaviors behaviors, final Command command)
       throws IOException {
     writer.startElement(HtmlElements.TOBAGO_BEHAVIOR);
-    writer.writeAttribute(CustomAttributes.EVENT, behaviors.name(), false);
+    writer.writeAttribute(CustomAttributes.EVENT, behaviors.getJsEvent(), false);
     writer.writeAttribute(CustomAttributes.CLIENT_ID, command.getClientId(), false);
     if (StringUtils.notEquals(command.getClientId(), command.getFieldId())) {
       writer.writeAttribute(CustomAttributes.FIELD_ID, command.getFieldId(), false);
diff --git a/tobago-core/src/test/java/org/apache/myfaces/tobago/util/EnumUnitTest.java b/tobago-core/src/test/java/org/apache/myfaces/tobago/util/EnumUnitTest.java
index 9ccbba823f..cacbb784ae 100644
--- a/tobago-core/src/test/java/org/apache/myfaces/tobago/util/EnumUnitTest.java
+++ b/tobago-core/src/test/java/org/apache/myfaces/tobago/util/EnumUnitTest.java
@@ -47,8 +47,12 @@ public abstract class EnumUnitTest {
       final String fieldName = field.getName();
       if (object instanceof String) {
         // case String constant
-        final String value = (String) object;
+        String value = (String) object;
         final String expected = constantCaseToEnum(fieldName);
+        int index = value.lastIndexOf('.');
+        if (index > 0) {
+          value = value.substring(index+1);
+        }
         Assertions.assertEquals(expected, value);
         Assertions.assertNotNull(enumType.getField(value), "exists");
       } else if (object.getClass().isAssignableFrom(enumType)) {
diff --git a/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/SheetController.java b/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/SheetController.java
index 2edf3a215b..c4b305d8f2 100644
--- a/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/SheetController.java
+++ b/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/SheetController.java
@@ -161,4 +161,12 @@ public class SheetController implements Serializable {
   public SelectItem[] getSelectableModes() {
     return SHEET_SELECTABLE;
   }
+
+  public String getSelectedRows() {
+    if (sheetState != null) {
+      return sheetState.getSelectedRows().stream().map(Object::toString).collect(Collectors.joining(", "));
+    } else {
+      return "";
+    }
+  }
 }
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/content/080-sheet/25-selection/Sheet_Selectionchange.xhtml b/tobago-example/tobago-example-demo/src/main/webapp/content/080-sheet/25-selection/Sheet_Selectionchange.xhtml
new file mode 100644
index 0000000000..c5ea7b5eb2
--- /dev/null
+++ b/tobago-example/tobago-example-demo/src/main/webapp/content/080-sheet/25-selection/Sheet_Selectionchange.xhtml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+
+<ui:composition template="/main.xhtml"
+                xmlns="http://www.w3.org/1999/xhtml"
+                xmlns:f="jakarta.faces.core"
+                xmlns:tc="http://myfaces.apache.org/tobago/component"
+                xmlns:ui="jakarta.faces.facelets">
+
+  <tc:panel id="panel">
+    <tc:out label="Timestamp" value="#{eventController.currentTimestamp}"/>
+    <tc:out label="selectedRows" value="#{sheetController.selectedRows}"/>
+  </tc:panel>
+
+  <tc:sheet id="s1" value="#{sheetController.solarList}" var="object" rows="4" state="#{sheetController.sheetState}">
+    <tc:style maxHeight="500px"/>
+    <f:ajax event="tobago.sheet.rowSelectionChange" render="::panel"/>
+    <tc:columnSelector/>
+    <tc:column label="Name">
+      <tc:out value="#{object.name}" labelLayout="skip"/>
+    </tc:column>
+    <tc:column label="Orbit">
+      <tc:out value="#{object.orbit}" labelLayout="skip"/>
+    </tc:column>
+    <tc:column label="Period (Days)">
+      <tc:out value="#{object.period}" labelLayout="skip"/>
+    </tc:column>
+    <tc:column label="Discoverer">
+      <tc:out value="#{object.discoverer}" labelLayout="skip"/>
+    </tc:column>
+    <tc:column label="Year">
+      <tc:out value="#{object.discoverYear}" labelLayout="skip"/>
+    </tc:column>
+  </tc:sheet>
+</ui:composition>
diff --git a/tobago-theme/tobago-theme-standard/src/main/js/tobago.js b/tobago-theme/tobago-theme-standard/src/main/js/tobago.js
index 64cb51018a..40eaab7aea 100644
--- a/tobago-theme/tobago-theme-standard/src/main/js/tobago.js
+++ b/tobago-theme/tobago-theme-standard/src/main/js/tobago.js
@@ -1,10 +1,10 @@
-!function(e){"function"==typeof define&&define.amd?define(e):e()}((function(){"use strict";var e;!function(e){e.ACTIVE="active",e.AUTOCOMPLETE="autocomplete",e.AUTOCOMPLETE_INPUT="autocomplete-input",e.BOTTOM_0="bottom-0",e.COLLAPSE="collapse",e.COLLAPSING="collapsing",e.D_NONE="d-none",e.DISABLED="disabled",e.DROPDOWN="dropdown",e.DROPDOWN_ITEM="dropdown-item",e.DROPDOWN_MENU="dropdown-menu",e.DROPDOWN_MENU_END="dropdown-menu-end",e.END_0="end-0",e.FADE="fade",e.FIXED_BOTTOM="fixed-bott [...]
+!function(e){"function"==typeof define&&define.amd?define(e):e()}((function(){"use strict";var e;!function(e){e.ACTIVE="active",e.AUTOCOMPLETE="autocomplete",e.AUTOCOMPLETE_INPUT="autocomplete-input",e.BOTTOM_0="bottom-0",e.COLLAPSE="collapse",e.COLLAPSING="collapsing",e.D_NONE="d-none",e.DISABLED="disabled",e.DROPDOWN="dropdown",e.DROPDOWN_ITEM="dropdown-item",e.DROPDOWN_MENU="dropdown-menu",e.DROPDOWN_MENU_END="dropdown-menu-end",e.END_0="end-0",e.FADE="fade",e.FIXED_BOTTOM="fixed-bott [...]
 /*!
       * Bootstrap v5.3.2 (https://getbootstrap.com/)
       * Copyright 2011-2023 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
       * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
       */
-const $e=new Map,Me={set(e,t,s){$e.has(e)||$e.set(e,new Map);const n=$e.get(e);n.has(t)||0===n.size?n.set(t,s):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(n.keys())[0]}.`)},get:(e,t)=>$e.has(e)&&$e.get(e).get(t)||null,remove(e,t){if(!$e.has(e))return;const s=$e.get(e);s.delete(t),0===s.size&&$e.delete(e)}},Pe="transitionend",Be=e=>(e&&window.CSS&&window.CSS.escape&&(e=e.replace(/#([^\s"#']+)/g,((e,t)=>`#${CSS.escape(t)}`))),e),H [...]
+const $e=new Map,Me={set(e,t,s){$e.has(e)||$e.set(e,new Map);const n=$e.get(e);n.has(t)||0===n.size?n.set(t,s):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(n.keys())[0]}.`)},get:(e,t)=>$e.has(e)&&$e.get(e).get(t)||null,remove(e,t){if(!$e.has(e))return;const s=$e.get(e);s.delete(t),0===s.size&&$e.delete(e)}},Pe="transitionend",Be=e=>(e&&window.CSS&&window.CSS.escape&&(e=e.replace(/#([^\s"#']+)/g,((e,t)=>`#${CSS.escape(t)}`))),e),H [...]
 /**
      * @license
      * Copyright 2017 Google LLC
@@ -15,5 +15,5 @@ const $e=new Map,Me={set(e,t,s){$e.has(e)||$e.set(e,new Map);const n=$e.get(e);n
       ${s>0?" tabindex='"+String(s)+"'":""}
       @click="${this.removeBadge.bind(this)}"
       @focus="${this.focusEvent.bind(this)}"
-      @blur="${this.blurEvent.bind(this)}"><i class='bi-x-lg'></i></button>`}removeBadge(e){const t=e.target.closest(".btn-group").dataset.tobagoValue,s=this.hiddenSelect.querySelector(`[value="${t}"]`);s.selected=!1;const n=this.selectField.querySelector(`[data-tobago-value="${t}"]`),i=n.previousElementSibling,o="SPAN"===n.nextElementSibling.tagName?n.nextElementSibling:null;i?i.querySelector("button.btn.badge").focus():o?o.querySelector("button.btn.badge").focus():(this.filterInput.dis [...]
+      @blur="${this.blurEvent.bind(this)}"><i class='bi-x-lg'></i></button>`}removeBadge(e){const t=e.target.closest(".btn-group").dataset.tobagoValue,s=this.hiddenSelect.querySelector(`[value="${t}"]`);s.selected=!1;const n=this.selectField.querySelector(`[data-tobago-value="${t}"]`),i=n.previousElementSibling,o="SPAN"===n.nextElementSibling.tagName?n.nextElementSibling:null;i?i.querySelector("button.btn.badge").focus():o?o.querySelector("button.btn.badge").focus():(this.filterInput.dis [...]
 //# sourceMappingURL=tobago.js.map
diff --git a/tobago-theme/tobago-theme-standard/src/main/js/tobago.js.map b/tobago-theme/tobago-theme-standard/src/main/js/tobago.js.map
index 3c381411a7..25b4ff49ee 100644
--- a/tobago-theme/tobago-theme-standard/src/main/js/tobago.js.map
+++ b/tobago-theme/tobago-theme-standard/src/main/js/tobago.js.map
@@ -1 +1 @@
-{"version":3,"file":"tobago.js","sources":["../ts/tobago-css.ts","../ts/tobago-bar.ts","../../../../node_modules/@popperjs/core/lib/enums.js","../../../../node_modules/@popperjs/core/lib/dom-utils/getNodeName.js","../../../../node_modules/@popperjs/core/lib/dom-utils/getWindow.js","../../../../node_modules/@popperjs/core/lib/dom-utils/instanceOf.js","../../../../node_modules/@popperjs/core/lib/modifiers/applyStyles.js","../../../../node_modules/@popperjs/core/lib/utils/getBasePlacement.j [...]
\ No newline at end of file
+{"version":3,"file":"tobago.js","sources":["../ts/tobago-css.ts","../ts/tobago-bar.ts","../../../../node_modules/@popperjs/core/lib/enums.js","../../../../node_modules/@popperjs/core/lib/dom-utils/getNodeName.js","../../../../node_modules/@popperjs/core/lib/dom-utils/getWindow.js","../../../../node_modules/@popperjs/core/lib/dom-utils/instanceOf.js","../../../../node_modules/@popperjs/core/lib/modifiers/applyStyles.js","../../../../node_modules/@popperjs/core/lib/utils/getBasePlacement.j [...]
\ No newline at end of file
diff --git a/tobago-theme/tobago-theme-standard/src/main/ts/tobago-client-behaviors.ts b/tobago-theme/tobago-theme-standard/src/main/ts/tobago-client-behaviors.ts
new file mode 100644
index 0000000000..84f743571d
--- /dev/null
+++ b/tobago-theme/tobago-theme-standard/src/main/ts/tobago-client-behaviors.ts
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export enum ClientBehaviors {
+  ACTION = "action",
+  BLUR = "blur",
+  CHANGE = "change",
+  CLICK = "click",
+  COMPLETE = "complete",
+  DBLCLICK = "dblclick",
+  FOCUS = "focus",
+  KEYDOWN = "keydown",
+  KEYPRESS = "keypress",
+  KEYUP = "keyup",
+  INPUT = "input",
+  LOAD = "load",
+  MOUSEOVER = "mouseover",
+  MOUSEOUT = "mouseout",
+  RELOAD = "reload",
+  RESIZE = "resize",
+  SUGGEST = "suggest",
+  ROW_SELECTION_CHANGE = "tobago.sheet.rowSelectionChange"
+}
diff --git a/tobago-theme/tobago-theme-standard/src/main/ts/tobago-sheet.ts b/tobago-theme/tobago-theme-standard/src/main/ts/tobago-sheet.ts
index ea9a05ea9c..58cfee636c 100644
--- a/tobago-theme/tobago-theme-standard/src/main/ts/tobago-sheet.ts
+++ b/tobago-theme/tobago-theme-standard/src/main/ts/tobago-sheet.ts
@@ -18,6 +18,7 @@
 import {Page} from "./tobago-page";
 import {Key} from "./tobago-key";
 import {Css} from "./tobago-css";
+import {ClientBehaviors} from "./tobago-client-behaviors";
 
 interface MousemoveData {
   columnIndex: number;
@@ -613,6 +614,7 @@ Type: ${data.type}`);
 
   clickOnCheckboxForAll(event: MouseEvent): void {
     const selectedSet = new Set<number>(JSON.parse(this.getHiddenSelected().value));
+    const oldSelectedSet = new Set<number>(selectedSet);
     const checkbox = event.currentTarget as HTMLInputElement;
     if (checkbox.checked) {
       this.selectAll(selectedSet);
@@ -620,6 +622,7 @@ Type: ${data.type}`);
       this.deselectAll(selectedSet);
     }
     this.getHiddenSelected().value = JSON.stringify(Array.from(selectedSet)); // write back to element
+    this.fireSelectionChange(oldSelectedSet, selectedSet);
   }
 
   clickOnRow(event: MouseEvent): void {
@@ -639,7 +642,7 @@ Type: ${data.type}`);
       const selector = this.getSelectorCheckbox(row);
       const selectionMode = this.dataset.tobagoSelectionMode;
       const selectedSet = new Set<number>(JSON.parse(this.getHiddenSelected().value));
-
+      const oldSelectedSet = new Set<number>(selectedSet);
       if ((!event.ctrlKey && !event.metaKey && !selector)
           || selectionMode === "single" || selectionMode === "singleOrNone") {
         this.deselectAll(selectedSet);
@@ -659,6 +662,19 @@ Type: ${data.type}`);
         this.toggleSelection(selectedSet, row, selector);
       }
       this.getHiddenSelected().value = JSON.stringify(Array.from(selectedSet)); // write back to element
+      this.fireSelectionChange(oldSelectedSet, selectedSet);
+    }
+  }
+
+  private fireSelectionChange(oldSelectedSet: Set<number>, newSelectedSet: Set<number>) {
+    const fireEvent = (oldSelectedSet, newSelectedSet) =>
+        oldSelectedSet.size == newSelectedSet.size && [...oldSelectedSet].every((x) => newSelectedSet.has(x));
+    if (fireEvent) {
+      this.dispatchEvent(new CustomEvent(ClientBehaviors.ROW_SELECTION_CHANGE, {
+        detail: {
+          selection: newSelectedSet,
+        },
+      }));
     }
   }