diff --git a/packages/calcite-components/src/components/accordion-item/accordion-item.e2e.ts b/packages/calcite-components/src/components/accordion-item/accordion-item.e2e.ts
index 08ed0754245..6e532bbdb81 100644
--- a/packages/calcite-components/src/components/accordion-item/accordion-item.e2e.ts
+++ b/packages/calcite-components/src/components/accordion-item/accordion-item.e2e.ts
@@ -218,4 +218,25 @@ describe("calcite-accordion-item", () => {
expect(headerContent.getAttribute("aria-expanded")).toBe("true");
});
+
+ it("should emit expanded/collapsed events when toggled", async () => {
+ const page = await newE2EPage();
+ await page.setContent(html``);
+ const item = await page.find("calcite-accordion-item");
+
+ const expandSpy = await page.spyOnEvent("calciteAccordionItemExpand");
+ const collapseSpy = await page.spyOnEvent("calciteAccordionItemCollapse");
+
+ item.setProperty("expanded", true);
+ await page.waitForChanges();
+ expect(await item.getProperty("expanded")).toBe(true);
+ expect(expandSpy).toHaveReceivedEventTimes(1);
+ expect(collapseSpy).toHaveReceivedEventTimes(0);
+
+ item.setProperty("expanded", false);
+ await page.waitForChanges();
+ expect(await item.getProperty("expanded")).toBe(false);
+ expect(expandSpy).toHaveReceivedEventTimes(1);
+ expect(collapseSpy).toHaveReceivedEventTimes(1);
+ });
});
diff --git a/packages/calcite-components/src/components/accordion-item/accordion-item.tsx b/packages/calcite-components/src/components/accordion-item/accordion-item.tsx
index 1b4e5b2e387..68f710da9c8 100644
--- a/packages/calcite-components/src/components/accordion-item/accordion-item.tsx
+++ b/packages/calcite-components/src/components/accordion-item/accordion-item.tsx
@@ -1,4 +1,5 @@
// @ts-strict-ignore
+import { PropertyValues } from "lit";
import { LitElement, property, createEvent, h, method, state, JsxNode } from "@arcgis/lumina";
import {
closestElementCrossShadowBoundary,
@@ -28,29 +29,29 @@ declare global {
* @slot actions-start - A slot for adding `calcite-action`s or content to the start side of the component's header.
*/
export class AccordionItem extends LitElement {
- // #region Static Members
+ //#region Static Members
static override styles = styles;
- // #endregion
+ //#endregion
- // #region Private Properties
+ //#region Private Properties
private headerEl: HTMLDivElement;
private focusSetter = useSetFocus()(this);
- // #endregion
+ //#endregion
- // #region State Properties
+ //#region State Properties
@state() hasActionsEnd = false;
@state() hasActionsStart = false;
- // #endregion
+ //#endregion
- // #region Public Properties
+ //#region Public Properties
/**
* The containing `accordion` element.
@@ -62,7 +63,7 @@ export class AccordionItem extends LitElement {
/** Specifies a description for the component. */
@property() description: string;
- /** When `true`, the component is expanded. */
+ /** When `true`, expands the component and its contents. */
@property({ reflect: true }) expanded = false;
/** Specifies heading text for the component. */
@@ -108,9 +109,9 @@ export class AccordionItem extends LitElement {
*/
@property({ reflect: true }) scale: Scale;
- // #endregion
+ //#endregion
- // #region Public Methods
+ //#region Public Methods
/**
* Sets focus on the component.
@@ -126,9 +127,15 @@ export class AccordionItem extends LitElement {
}, options);
}
- // #endregion
+ //#endregion
- // #region Events
+ //#region Events
+
+ /** Fires when the component's content area is collapsed. */
+ calciteAccordionItemCollapse = createEvent({ cancelable: false });
+
+ /** Fires when the component's content area is expanded. */
+ calciteAccordionItemExpand = createEvent({ cancelable: false });
/** @private */
calciteInternalAccordionItemClose = createEvent({ cancelable: false });
@@ -136,9 +143,9 @@ export class AccordionItem extends LitElement {
/** @private */
calciteInternalAccordionItemSelect = createEvent({ cancelable: false });
- // #endregion
+ //#endregion
- // #region Lifecycle
+ //#region Lifecycle
constructor() {
super();
@@ -155,9 +162,19 @@ export class AccordionItem extends LitElement {
);
}
- // #endregion
+ override willUpdate(changes: PropertyValues): void {
+ if (changes.has("expanded") && this.hasUpdated) {
+ if (this.expanded) {
+ this.calciteAccordionItemExpand.emit();
+ } else {
+ this.calciteAccordionItemCollapse.emit();
+ }
+ }
+ }
+
+ //#endregion
- // #region Private Methods
+ //#region Private Methods
private keyDownHandler(event: KeyboardEvent): void {
if (event.target === this.el) {
@@ -255,9 +272,9 @@ export class AccordionItem extends LitElement {
});
}
- // #endregion
+ //#endregion
- // #region Rendering
+ //#region Rendering
private renderActionsStart(): JsxNode {
return (
@@ -355,5 +372,5 @@ export class AccordionItem extends LitElement {
);
}
- // #endregion
+ //#endregion
}
diff --git a/packages/calcite-components/src/components/action-bar/action-bar.e2e.ts b/packages/calcite-components/src/components/action-bar/action-bar.e2e.ts
index ff744562a67..7d5efe311f5 100755
--- a/packages/calcite-components/src/components/action-bar/action-bar.e2e.ts
+++ b/packages/calcite-components/src/components/action-bar/action-bar.e2e.ts
@@ -611,5 +611,26 @@ describe("calcite-action-bar", () => {
},
);
});
+
+ it("should emit expanded/collapsed events when toggled", async () => {
+ const page = await newE2EPage();
+ await page.setContent(html``);
+ const item = await page.find("calcite-action-bar");
+
+ const expandSpy = await page.spyOnEvent("calciteActionBarExpand");
+ const collapseSpy = await page.spyOnEvent("calciteActionBarCollapse");
+
+ item.setProperty("expanded", true);
+ await page.waitForChanges();
+ expect(await item.getProperty("expanded")).toBe(true);
+ expect(expandSpy).toHaveReceivedEventTimes(1);
+ expect(collapseSpy).toHaveReceivedEventTimes(0);
+
+ item.setProperty("expanded", false);
+ await page.waitForChanges();
+ expect(await item.getProperty("expanded")).toBe(false);
+ expect(expandSpy).toHaveReceivedEventTimes(1);
+ expect(collapseSpy).toHaveReceivedEventTimes(1);
+ });
});
});
diff --git a/packages/calcite-components/src/components/action-bar/action-bar.tsx b/packages/calcite-components/src/components/action-bar/action-bar.tsx
index 573ee782fa8..35bdeb94536 100755
--- a/packages/calcite-components/src/components/action-bar/action-bar.tsx
+++ b/packages/calcite-components/src/components/action-bar/action-bar.tsx
@@ -130,7 +130,7 @@ export class ActionBar extends LitElement {
/** When `true`, the expand-toggling behavior is disabled. */
@property({ reflect: true }) expandDisabled = false;
- /** When `true`, the component is expanded. */
+ /** When `true`, expands the component and its contents. */
@property({ reflect: true }) expanded = false;
/** Specifies the layout direction of the actions. */
@@ -190,6 +190,12 @@ export class ActionBar extends LitElement {
//#region Events
+ /** Fires when the component's content area is collapsed. */
+ calciteActionBarCollapse = createEvent({ cancelable: false });
+
+ /** Fires when the component's content area is expanded. */
+ calciteActionBarExpand = createEvent({ cancelable: false });
+
/** Fires when the `expanded` property is toggled. */
calciteActionBarToggle = createEvent({ cancelable: false });
@@ -219,10 +225,6 @@ export class ActionBar extends LitElement {
this.overflowActions();
}
- if (changes.has("expanded") && this.hasUpdated) {
- this.expandedHandler();
- }
-
if (changes.has("layout") && (this.hasUpdated || this.layout !== "vertical")) {
this.updateGroups();
}
@@ -233,6 +235,15 @@ export class ActionBar extends LitElement {
) {
this.overflowActionsDisabledHandler(this.overflowActionsDisabled);
}
+
+ if (changes.has("expanded") && this.hasUpdated) {
+ this.expandedHandler();
+ if (this.expanded) {
+ this.calciteActionBarExpand.emit();
+ } else {
+ this.calciteActionBarCollapse.emit();
+ }
+ }
}
loaded(): void {
diff --git a/packages/calcite-components/src/components/action-group/action-group.e2e.ts b/packages/calcite-components/src/components/action-group/action-group.e2e.ts
index 1615317bd77..a253ce2654b 100755
--- a/packages/calcite-components/src/components/action-group/action-group.e2e.ts
+++ b/packages/calcite-components/src/components/action-group/action-group.e2e.ts
@@ -134,4 +134,25 @@ describe("calcite-action-group", () => {
);
});
});
+
+ it("should emit expanded/collapsed events when toggled", async () => {
+ const page = await newE2EPage();
+ await page.setContent(html``);
+ const item = await page.find("calcite-action-group");
+
+ const expandSpy = await page.spyOnEvent("calciteActionGroupExpand");
+ const collapseSpy = await page.spyOnEvent("calciteActionGroupCollapse");
+
+ item.setProperty("expanded", true);
+ await page.waitForChanges();
+ expect(await item.getProperty("expanded")).toBe(true);
+ expect(expandSpy).toHaveReceivedEventTimes(1);
+ expect(collapseSpy).toHaveReceivedEventTimes(0);
+
+ item.setProperty("expanded", false);
+ await page.waitForChanges();
+ expect(await item.getProperty("expanded")).toBe(false);
+ expect(expandSpy).toHaveReceivedEventTimes(1);
+ expect(collapseSpy).toHaveReceivedEventTimes(1);
+ });
});
diff --git a/packages/calcite-components/src/components/action-group/action-group.tsx b/packages/calcite-components/src/components/action-group/action-group.tsx
index 46df96ff3c1..af1de488bc9 100755
--- a/packages/calcite-components/src/components/action-group/action-group.tsx
+++ b/packages/calcite-components/src/components/action-group/action-group.tsx
@@ -1,6 +1,15 @@
// @ts-strict-ignore
import { PropertyValues } from "lit";
-import { LitElement, property, h, method, state, JsxNode, ToEvents } from "@arcgis/lumina";
+import {
+ LitElement,
+ property,
+ h,
+ method,
+ state,
+ JsxNode,
+ ToEvents,
+ createEvent,
+} from "@arcgis/lumina";
import { SLOTS as ACTION_MENU_SLOTS } from "../action-menu/resources";
import { Layout, Scale } from "../interfaces";
import { FlipPlacement, LogicalPlacement, OverlayPositioning } from "../../utils/floating-ui";
@@ -57,7 +66,7 @@ export class ActionGroup extends LitElement {
/** Indicates number of columns. */
@property({ type: Number, reflect: true }) columns: Columns;
- /** When `true`, the component is expanded. */
+ /** When `true`, expands the component and its contents. */
@property({ reflect: true }) expanded = false;
/** Accessible name for the component. */
@@ -114,6 +123,16 @@ export class ActionGroup extends LitElement {
//#endregion
+ //#region Events
+
+ /** Fires when the component's content area is collapsed. */
+ calciteActionGroupCollapse = createEvent({ cancelable: false });
+
+ /** Fires when the component's content area is expanded. */
+ calciteActionGroupExpand = createEvent({ cancelable: false });
+
+ //#endregion
+
//#region Lifecycle
override willUpdate(changes: PropertyValues): void {
@@ -121,8 +140,18 @@ export class ActionGroup extends LitElement {
To account for this semantics change, the checks for (this.hasUpdated || value != defaultValue) was added in this method
Please refactor your code to reduce the need for this check.
Docs: https://qawebgis.esri.com/arcgis-components/?path=/docs/lumina-transition-from-stencil--docs#watching-for-property-changes */
- if (changes.has("expanded") && (this.hasUpdated || this.expanded !== false)) {
- this.menuOpen = false;
+
+ if (changes.has("expanded")) {
+ if (this.hasUpdated || this.expanded !== false) {
+ this.menuOpen = false;
+ }
+ if (this.hasUpdated) {
+ if (this.expanded) {
+ this.calciteActionGroupExpand.emit();
+ } else {
+ this.calciteActionGroupCollapse.emit();
+ }
+ }
}
}
diff --git a/packages/calcite-components/src/components/action-menu/action-menu.e2e.ts b/packages/calcite-components/src/components/action-menu/action-menu.e2e.ts
index 5b71b8058a5..c02594ef8aa 100755
--- a/packages/calcite-components/src/components/action-menu/action-menu.e2e.ts
+++ b/packages/calcite-components/src/components/action-menu/action-menu.e2e.ts
@@ -622,6 +622,27 @@ describe("calcite-action-menu", () => {
});
});
+ it("should emit expanded/collapsed events when toggled", async () => {
+ const page = await newE2EPage();
+ await page.setContent(html``);
+ const item = await page.find("calcite-action-menu");
+
+ const expandSpy = await page.spyOnEvent("calciteActionMenuExpand");
+ const collapseSpy = await page.spyOnEvent("calciteActionMenuCollapse");
+
+ item.setProperty("expanded", true);
+ await page.waitForChanges();
+ expect(await item.getProperty("expanded")).toBe(true);
+ expect(expandSpy).toHaveReceivedEventTimes(1);
+ expect(collapseSpy).toHaveReceivedEventTimes(0);
+
+ item.setProperty("expanded", false);
+ await page.waitForChanges();
+ expect(await item.getProperty("expanded")).toBe(false);
+ expect(expandSpy).toHaveReceivedEventTimes(1);
+ expect(collapseSpy).toHaveReceivedEventTimes(1);
+ });
+
describe("theme", () => {
themed(
html`
diff --git a/packages/calcite-components/src/components/action-menu/action-menu.tsx b/packages/calcite-components/src/components/action-menu/action-menu.tsx
index 63aff4ee8fa..eb54395af0c 100755
--- a/packages/calcite-components/src/components/action-menu/action-menu.tsx
+++ b/packages/calcite-components/src/components/action-menu/action-menu.tsx
@@ -37,13 +37,13 @@ const SUPPORTED_MENU_NAV_KEYS = ["ArrowUp", "ArrowDown", "End", "Home"];
* @slot tooltip - A slot for adding a tooltip for the menu.
*/
export class ActionMenu extends LitElement {
- // #region Static Members
+ //#region Static Members
static override styles = styles;
- // #endregion
+ //#endregion
- // #region Private Properties
+ //#region Private Properties
private guid = guid();
@@ -121,22 +121,22 @@ export class ActionMenu extends LitElement {
private focusSetter = useSetFocus()(this);
- // #endregion
+ //#endregion
- // #region State Properties
+ //#region State Properties
@state() activeMenuItemIndex = -1;
@state() menuButtonEl: Action["el"];
- // #endregion
+ //#endregion
- // #region Public Properties
+ //#region Public Properties
/** Specifies the appearance of the component. */
@property({ reflect: true }) appearance: Extract<"solid" | "transparent", Appearance> = "solid";
- /** When `true`, the component is expanded. */
+ /** When `true`, expands the component and its contents. */
@property({ reflect: true }) expanded = false;
/** Specifies the component's fallback slotted content `placement` when it's initial or specified `placement` has insufficient space available. */
@@ -176,9 +176,9 @@ export class ActionMenu extends LitElement {
/** Specifies the size of the component's trigger `calcite-action`. */
@property({ reflect: true }) scale: Scale = "m";
- // #endregion
+ //#endregion
- // #region Public Methods
+ //#region Public Methods
/**
* Sets focus on the component.
@@ -194,16 +194,22 @@ export class ActionMenu extends LitElement {
}, options);
}
- // #endregion
+ //#endregion
- // #region Events
+ //#region Events
+
+ /** Fires when the component's content area is collapsed. */
+ calciteActionMenuCollapse = createEvent({ cancelable: false });
+
+ /** Fires when the component's content area is expanded. */
+ calciteActionMenuExpand = createEvent({ cancelable: false });
/** Fires when the `open` property is toggled. */
calciteActionMenuOpen = createEvent({ cancelable: false });
- // #endregion
+ //#endregion
- // #region Lifecycle
+ //#region Lifecycle
override connectedCallback(): void {
this.connectMenuButtonEl();
@@ -224,15 +230,23 @@ export class ActionMenu extends LitElement {
) {
this.updateActions(this.actionElements);
}
+
+ if (changes.has("expanded") && this.hasUpdated) {
+ if (this.expanded) {
+ this.calciteActionMenuExpand.emit();
+ } else {
+ this.calciteActionMenuCollapse.emit();
+ }
+ }
}
override disconnectedCallback(): void {
this.disconnectMenuButtonEl();
}
- // #endregion
+ //#endregion
- // #region Private Methods
+ //#region Private Methods
private expandedHandler(): void {
this.open = false;
@@ -453,9 +467,9 @@ export class ActionMenu extends LitElement {
this.open = false;
}
- // #endregion
+ //#endregion
- // #region Rendering
+ //#region Rendering
private renderMenuButton(): JsxNode {
const { appearance, label, scale, expanded } = this;
@@ -533,5 +547,5 @@ export class ActionMenu extends LitElement {
);
}
- // #endregion
+ //#endregion
}
diff --git a/packages/calcite-components/src/components/action-pad/action-pad.e2e.ts b/packages/calcite-components/src/components/action-pad/action-pad.e2e.ts
index 4da67f0ec1a..b02be0c9239 100755
--- a/packages/calcite-components/src/components/action-pad/action-pad.e2e.ts
+++ b/packages/calcite-components/src/components/action-pad/action-pad.e2e.ts
@@ -366,6 +366,27 @@ describe("calcite-action-pad", () => {
}
});
+ it("should emit expanded/collapsed events when toggled", async () => {
+ const page = await newE2EPage();
+ await page.setContent(html``);
+ const item = await page.find("calcite-action-pad");
+
+ const expandSpy = await page.spyOnEvent("calciteActionPadExpand");
+ const collapseSpy = await page.spyOnEvent("calciteActionPadCollapse");
+
+ item.setProperty("expanded", true);
+ await page.waitForChanges();
+ expect(await item.getProperty("expanded")).toBe(true);
+ expect(expandSpy).toHaveReceivedEventTimes(1);
+ expect(collapseSpy).toHaveReceivedEventTimes(0);
+
+ item.setProperty("expanded", false);
+ await page.waitForChanges();
+ expect(await item.getProperty("expanded")).toBe(false);
+ expect(expandSpy).toHaveReceivedEventTimes(1);
+ expect(collapseSpy).toHaveReceivedEventTimes(1);
+ });
+
describe("theme", () => {
describe("default", () => {
themed("calcite-action-pad", {
diff --git a/packages/calcite-components/src/components/action-pad/action-pad.tsx b/packages/calcite-components/src/components/action-pad/action-pad.tsx
index 7b7d7ea2d86..177ea0b4235 100755
--- a/packages/calcite-components/src/components/action-pad/action-pad.tsx
+++ b/packages/calcite-components/src/components/action-pad/action-pad.tsx
@@ -71,7 +71,7 @@ export class ActionPad extends LitElement {
/** When `true`, the expand-toggling behavior is disabled. */
@property({ reflect: true }) expandDisabled = false;
- /** When `true`, the component is expanded. */
+ /** When `true`, expands the component and its contents. */
@property({ reflect: true }) expanded = false;
/** Indicates the layout of the component. */
@@ -118,6 +118,12 @@ export class ActionPad extends LitElement {
//#region Events
+ /** Fires when the component's content area is collapsed. */
+ calciteActionPadCollapse = createEvent({ cancelable: false });
+
+ /** Fires when the component's content area is expanded. */
+ calciteActionPadExpand = createEvent({ cancelable: false });
+
/** Fires when the `expanded` property is toggled. */
calciteActionPadToggle = createEvent({ cancelable: false });
@@ -154,6 +160,14 @@ export class ActionPad extends LitElement {
if (changes.has("layout") && (this.hasUpdated || this.layout !== "vertical")) {
this.updateGroups();
}
+
+ if (changes.has("expanded") && this.hasUpdated) {
+ if (this.expanded) {
+ this.calciteActionPadExpand.emit();
+ } else {
+ this.calciteActionPadCollapse.emit();
+ }
+ }
}
override disconnectedCallback(): void {
diff --git a/packages/calcite-components/src/components/block-section/block-section.e2e.ts b/packages/calcite-components/src/components/block-section/block-section.e2e.ts
index 5b58102b565..0a3f2b45ed8 100644
--- a/packages/calcite-components/src/components/block-section/block-section.e2e.ts
+++ b/packages/calcite-components/src/components/block-section/block-section.e2e.ts
@@ -261,6 +261,27 @@ describe("calcite-block-section", () => {
expect(toggle.getAttribute("aria-expanded")).toBe("false");
}
+ it("should emit expanded/collapsed events when toggled", async () => {
+ const page = await newE2EPage();
+ await page.setContent(html``);
+ const item = await page.find("calcite-block-section");
+
+ const expandSpy = await page.spyOnEvent("calciteBlockSectionExpand");
+ const collapseSpy = await page.spyOnEvent("calciteBlockSectionCollapse");
+
+ item.setProperty("expanded", true);
+ await page.waitForChanges();
+ expect(await item.getProperty("expanded")).toBe(true);
+ expect(expandSpy).toHaveReceivedEventTimes(1);
+ expect(collapseSpy).toHaveReceivedEventTimes(0);
+
+ item.setProperty("expanded", false);
+ await page.waitForChanges();
+ expect(await item.getProperty("expanded")).toBe(false);
+ expect(expandSpy).toHaveReceivedEventTimes(1);
+ expect(collapseSpy).toHaveReceivedEventTimes(1);
+ });
+
describe("theme", () => {
describe("default", () => {
themed(
diff --git a/packages/calcite-components/src/components/block-section/block-section.tsx b/packages/calcite-components/src/components/block-section/block-section.tsx
index f0b7e63bbe8..2c7124c5694 100644
--- a/packages/calcite-components/src/components/block-section/block-section.tsx
+++ b/packages/calcite-components/src/components/block-section/block-section.tsx
@@ -1,4 +1,5 @@
// @ts-strict-ignore
+import { PropertyValues } from "lit";
import { LitElement, property, createEvent, Fragment, h, method, JsxNode } from "@arcgis/lumina";
import { isActivationKey } from "../../utils/key";
import { FlipContext, Status } from "../interfaces";
@@ -40,7 +41,7 @@ export class BlockSection extends LitElement {
//#region Public Properties
- /** When `true`, the component is expanded to show child components. */
+ /** When `true`, expands the component and its contents. */
@property({ reflect: true }) expanded = false;
/** Specifies an icon to display at the end of the component. */
@@ -114,11 +115,31 @@ export class BlockSection extends LitElement {
//#region Events
+ /** Fires when the component's content area is collapsed. */
+ calciteBlockSectionCollapse = createEvent({ cancelable: false });
+
+ /** Fires when the component's content area is expanded. */
+ calciteBlockSectionExpand = createEvent({ cancelable: false });
+
/** Fires when the header has been clicked. */
calciteBlockSectionToggle = createEvent({ cancelable: false });
//#endregion
+ //#region Lifecycle
+
+ override willUpdate(changes: PropertyValues): void {
+ if (changes.has("expanded") && this.hasUpdated) {
+ if (this.expanded) {
+ this.calciteBlockSectionExpand.emit();
+ } else {
+ this.calciteBlockSectionCollapse.emit();
+ }
+ }
+ }
+
+ //#endregion
+
//#region Private Methods
private handleHeaderKeyDown(event: KeyboardEvent): void {
diff --git a/packages/calcite-components/src/components/block/block.e2e.ts b/packages/calcite-components/src/components/block/block.e2e.ts
index a968f63a933..e4e823ce2da 100644
--- a/packages/calcite-components/src/components/block/block.e2e.ts
+++ b/packages/calcite-components/src/components/block/block.e2e.ts
@@ -476,6 +476,27 @@ describe("calcite-block", () => {
expect(article.getAttribute("aria-label")).toEqual(label);
});
+ it("should emit expanded/collapsed events when toggled", async () => {
+ const page = await newE2EPage();
+ await page.setContent(html``);
+ const item = await page.find("calcite-block");
+
+ const expandSpy = await page.spyOnEvent("calciteBlockExpand");
+ const collapseSpy = await page.spyOnEvent("calciteBlockCollapse");
+
+ item.setProperty("expanded", true);
+ await page.waitForChanges();
+ expect(await item.getProperty("expanded")).toBe(true);
+ expect(expandSpy).toHaveReceivedEventTimes(1);
+ expect(collapseSpy).toHaveReceivedEventTimes(0);
+
+ item.setProperty("expanded", false);
+ await page.waitForChanges();
+ expect(await item.getProperty("expanded")).toBe(false);
+ expect(expandSpy).toHaveReceivedEventTimes(1);
+ expect(collapseSpy).toHaveReceivedEventTimes(1);
+ });
+
describe("translation support", () => {
t9n("calcite-block");
});
diff --git a/packages/calcite-components/src/components/block/block.tsx b/packages/calcite-components/src/components/block/block.tsx
index 77db2b9d197..b2edcebc574 100644
--- a/packages/calcite-components/src/components/block/block.tsx
+++ b/packages/calcite-components/src/components/block/block.tsx
@@ -102,7 +102,7 @@ export class Block extends LitElement implements InteractiveComponent, OpenClose
*/
@property({ reflect: true }) dragHandle = false;
- /** When `true`, the component is expanded to show child components. */
+ /** When `true`, expands the component and its contents. */
@property({ reflect: true }) expanded = false;
/**
@@ -220,12 +220,6 @@ export class Block extends LitElement implements InteractiveComponent, OpenClose
//#region Events
- /**
- *
- * @private
- */
- calciteInternalBlockUpdateMoveToItems = createEvent({ cancelable: false });
-
/** Fires when the component is requested to be closed and before the closing transition begins. */
calciteBlockBeforeClose = createEvent({ cancelable: false });
@@ -235,6 +229,12 @@ export class Block extends LitElement implements InteractiveComponent, OpenClose
/** Fires when the component is closed and animation is complete. */
calciteBlockClose = createEvent({ cancelable: false });
+ /** Fires when the component's content area is collapsed. */
+ calciteBlockCollapse = createEvent({ cancelable: false });
+
+ /** Fires when the component's content area is expanded. */
+ calciteBlockExpand = createEvent({ cancelable: false });
+
/** Fires when the component is open and animation is complete. */
calciteBlockOpen = createEvent({ cancelable: false });
@@ -257,6 +257,12 @@ export class Block extends LitElement implements InteractiveComponent, OpenClose
*/
calciteBlockToggle = createEvent({ cancelable: false });
+ /**
+ *
+ * @private
+ */
+ calciteInternalBlockUpdateMoveToItems = createEvent({ cancelable: false });
+
//#endregion
//#region Lifecycle
@@ -285,6 +291,14 @@ export class Block extends LitElement implements InteractiveComponent, OpenClose
if (changes.has("sortHandleOpen") && (this.hasUpdated || this.sortHandleOpen !== false)) {
this.sortHandleOpenHandler();
}
+
+ if (changes.has("expanded") && this.hasUpdated) {
+ if (this.expanded) {
+ this.calciteBlockExpand.emit();
+ } else {
+ this.calciteBlockCollapse.emit();
+ }
+ }
}
override updated(): void {
diff --git a/packages/calcite-components/src/components/flow-item/flow-item.e2e.ts b/packages/calcite-components/src/components/flow-item/flow-item.e2e.ts
index cdcee6bb940..544feccf9dc 100644
--- a/packages/calcite-components/src/components/flow-item/flow-item.e2e.ts
+++ b/packages/calcite-components/src/components/flow-item/flow-item.e2e.ts
@@ -423,6 +423,27 @@ describe("calcite-flow-item", () => {
expect(await flowItem.getProperty("closed")).toBe(false);
});
+ it("should emit expanded/collapsed events when toggled", async () => {
+ const page = await newE2EPage();
+ await page.setContent(html``);
+ const item = await page.find("calcite-flow-item");
+
+ const expandSpy = await page.spyOnEvent("calciteFlowItemExpand");
+ const collapseSpy = await page.spyOnEvent("calciteFlowItemCollapse");
+
+ item.setProperty("collapsed", true);
+ await page.waitForChanges();
+ expect(await item.getProperty("collapsed")).toBe(true);
+ expect(expandSpy).toHaveReceivedEventTimes(0);
+ expect(collapseSpy).toHaveReceivedEventTimes(1);
+
+ item.setProperty("collapsed", false);
+ await page.waitForChanges();
+ expect(await item.getProperty("collapsed")).toBe(false);
+ expect(expandSpy).toHaveReceivedEventTimes(1);
+ expect(collapseSpy).toHaveReceivedEventTimes(1);
+ });
+
describe("theme", () => {
themed(html``, {
"--calcite-flow-corner-radius": {
diff --git a/packages/calcite-components/src/components/flow-item/flow-item.tsx b/packages/calcite-components/src/components/flow-item/flow-item.tsx
index 78df6ae75db..064754503ff 100644
--- a/packages/calcite-components/src/components/flow-item/flow-item.tsx
+++ b/packages/calcite-components/src/components/flow-item/flow-item.tsx
@@ -188,6 +188,12 @@ export class FlowItem extends LitElement implements InteractiveComponent {
/** Fires when the close button is clicked. */
calciteFlowItemClose = createEvent({ cancelable: false });
+ /** Fires when the component's content area is collapsed. */
+ calciteFlowItemCollapse = createEvent({ cancelable: false });
+
+ /** Fires when the component's content area is expanded. */
+ calciteFlowItemExpand = createEvent({ cancelable: false });
+
/** Fires when the content is scrolled. */
calciteFlowItemScroll = createEvent({ cancelable: false });
@@ -209,6 +215,13 @@ export class FlowItem extends LitElement implements InteractiveComponent {
if (changes.has("selected") && (this.hasUpdated || this.selected !== false)) {
this.calciteInternalFlowItemChange.emit();
}
+ if (changes.has("collapsed") && this.hasUpdated) {
+ if (this.collapsed) {
+ this.calciteFlowItemCollapse.emit();
+ } else {
+ this.calciteFlowItemExpand.emit();
+ }
+ }
}
override updated(): void {
diff --git a/packages/calcite-components/src/components/list-item/list-item.e2e.ts b/packages/calcite-components/src/components/list-item/list-item.e2e.ts
index d476f6d84ea..a120e118168 100755
--- a/packages/calcite-components/src/components/list-item/list-item.e2e.ts
+++ b/packages/calcite-components/src/components/list-item/list-item.e2e.ts
@@ -520,6 +520,27 @@ describe("calcite-list-item", () => {
expect(icon).toBe(null);
});
+ it("should emit expanded/collapsed events when toggled", async () => {
+ const page = await newE2EPage();
+ await page.setContent(html``);
+ const item = await page.find("calcite-list-item");
+
+ const expandSpy = await page.spyOnEvent("calciteListItemExpand");
+ const collapseSpy = await page.spyOnEvent("calciteListItemCollapse");
+
+ item.setProperty("expanded", true);
+ await page.waitForChanges();
+ expect(await item.getProperty("expanded")).toBe(true);
+ expect(expandSpy).toHaveReceivedEventTimes(1);
+ expect(collapseSpy).toHaveReceivedEventTimes(0);
+
+ item.setProperty("expanded", false);
+ await page.waitForChanges();
+ expect(await item.getProperty("expanded")).toBe(false);
+ expect(expandSpy).toHaveReceivedEventTimes(1);
+ expect(collapseSpy).toHaveReceivedEventTimes(1);
+ });
+
describe("themed", () => {
describe(`selection-appearance="icon"`, () => {
themed(
diff --git a/packages/calcite-components/src/components/list-item/list-item.tsx b/packages/calcite-components/src/components/list-item/list-item.tsx
index 52c29848928..4b1472e85dc 100644
--- a/packages/calcite-components/src/components/list-item/list-item.tsx
+++ b/packages/calcite-components/src/components/list-item/list-item.tsx
@@ -136,7 +136,7 @@ export class ListItem extends LitElement implements InteractiveComponent, Sortab
*/
@property({ reflect: true }) dragHandle = false;
- /** When `true`, the item is expanded to show child components. */
+ /** When `true`, expands the component and its contents. */
@property({ reflect: true }) expanded = false;
/**
@@ -338,6 +338,12 @@ export class ListItem extends LitElement implements InteractiveComponent, Sortab
/** Fires when the close button is clicked. */
calciteListItemClose = createEvent({ cancelable: false });
+ /** Fires when the component's content area is collapsed. */
+ calciteListItemCollapse = createEvent({ cancelable: false });
+
+ /** Fires when the component's content area is expanded. */
+ calciteListItemExpand = createEvent({ cancelable: false });
+
/** Fires when the component is selected. */
calciteListItemSelect = createEvent({ cancelable: false });
@@ -401,10 +407,6 @@ export class ListItem extends LitElement implements InteractiveComponent, Sortab
this.handleDisabledChange();
}
- if (changes.has("expanded") && (this.hasUpdated || this.expanded !== false)) {
- this.handleExpandedChange();
- }
-
if (changes.has("selected") && (this.hasUpdated || this.selected !== false)) {
this.handleSelectedChange();
}
@@ -416,6 +418,15 @@ export class ListItem extends LitElement implements InteractiveComponent, Sortab
if (changes.has("displayMode") && this.hasUpdated) {
this.handleExpandableChange(this.defaultSlotEl.value);
}
+
+ if (changes.has("expanded") && this.hasUpdated) {
+ if (this.expanded) {
+ this.handleExpandedChange();
+ this.calciteListItemExpand.emit();
+ } else {
+ this.calciteListItemCollapse.emit();
+ }
+ }
}
override updated(): void {
diff --git a/packages/calcite-components/src/components/panel/panel.e2e.ts b/packages/calcite-components/src/components/panel/panel.e2e.ts
index 342c7f0a54c..f466711f216 100644
--- a/packages/calcite-components/src/components/panel/panel.e2e.ts
+++ b/packages/calcite-components/src/components/panel/panel.e2e.ts
@@ -744,6 +744,27 @@ describe("calcite-panel", () => {
});
});
+ it("should emit expanded/collapsed events when toggled", async () => {
+ const page = await newE2EPage();
+ await page.setContent(html``);
+ const item = await page.find("calcite-panel");
+
+ const expandSpy = await page.spyOnEvent("calcitePanelExpand");
+ const collapseSpy = await page.spyOnEvent("calcitePanelCollapse");
+
+ item.setProperty("collapsed", true);
+ await page.waitForChanges();
+ expect(await item.getProperty("collapsed")).toBe(true);
+ expect(expandSpy).toHaveReceivedEventTimes(0);
+ expect(collapseSpy).toHaveReceivedEventTimes(1);
+
+ item.setProperty("collapsed", false);
+ await page.waitForChanges();
+ expect(await item.getProperty("collapsed")).toBe(false);
+ expect(expandSpy).toHaveReceivedEventTimes(1);
+ expect(collapseSpy).toHaveReceivedEventTimes(1);
+ });
+
describe("theme", () => {
themed(
html`): void {
+ if (changes.has("collapsed") && this.hasUpdated) {
+ if (this.collapsed) {
+ this.calcitePanelCollapse.emit();
+ } else {
+ this.calcitePanelExpand.emit();
+ }
+ }
+ }
+
override updated(): void {
updateHostInteraction(this);
}
diff --git a/packages/calcite-components/src/components/shell-panel/shell-panel.e2e.ts b/packages/calcite-components/src/components/shell-panel/shell-panel.e2e.ts
index 431ed75b6a4..eba1605e203 100644
--- a/packages/calcite-components/src/components/shell-panel/shell-panel.e2e.ts
+++ b/packages/calcite-components/src/components/shell-panel/shell-panel.e2e.ts
@@ -565,6 +565,27 @@ describe("calcite-shell-panel", () => {
t9n("calcite-shell-panel");
});
+ it("should emit expanded/collapsed events when toggled", async () => {
+ const page = await newE2EPage();
+ await page.setContent(html``);
+ const item = await page.find("calcite-shell-panel");
+
+ const expandSpy = await page.spyOnEvent("calciteShellPanelExpand");
+ const collapseSpy = await page.spyOnEvent("calciteShellPanelCollapse");
+
+ item.setProperty("collapsed", true);
+ await page.waitForChanges();
+ expect(await item.getProperty("collapsed")).toBe(true);
+ expect(expandSpy).toHaveReceivedEventTimes(0);
+ expect(collapseSpy).toHaveReceivedEventTimes(1);
+
+ item.setProperty("collapsed", false);
+ await page.waitForChanges();
+ expect(await item.getProperty("collapsed")).toBe(false);
+ expect(expandSpy).toHaveReceivedEventTimes(1);
+ expect(collapseSpy).toHaveReceivedEventTimes(1);
+ });
+
describe("themed", () => {
describe("default", () => {
themed(html``, {
diff --git a/packages/calcite-components/src/components/shell-panel/shell-panel.tsx b/packages/calcite-components/src/components/shell-panel/shell-panel.tsx
index b23bb8bd108..bc8e8966acd 100755
--- a/packages/calcite-components/src/components/shell-panel/shell-panel.tsx
+++ b/packages/calcite-components/src/components/shell-panel/shell-panel.tsx
@@ -134,6 +134,12 @@ export class ShellPanel extends LitElement {
/** @private */
calciteInternalShellPanelResizeStart = createEvent({ cancelable: false });
+ /** Fires when the component's content area is collapsed. */
+ calciteShellPanelCollapse = createEvent({ cancelable: false });
+
+ /** Fires when the component's content area is expanded. */
+ calciteShellPanelExpand = createEvent({ cancelable: false });
+
//#endregion
//#region Lifecycle
@@ -146,6 +152,13 @@ export class ShellPanel extends LitElement {
if (changes.has("layout") && (this.hasUpdated || this.layout !== "vertical")) {
this.setActionBarsLayout(this.actionBars);
}
+ if (changes.has("collapsed") && this.hasUpdated) {
+ if (this.collapsed) {
+ this.calciteShellPanelCollapse.emit();
+ } else {
+ this.calciteShellPanelExpand.emit();
+ }
+ }
}
override disconnectedCallback(): void {
diff --git a/packages/calcite-components/src/components/tree-item/tree-item.e2e.ts b/packages/calcite-components/src/components/tree-item/tree-item.e2e.ts
index ef1ed49ab0d..22630b4555a 100644
--- a/packages/calcite-components/src/components/tree-item/tree-item.e2e.ts
+++ b/packages/calcite-components/src/components/tree-item/tree-item.e2e.ts
@@ -429,6 +429,27 @@ describe("calcite-tree-item", () => {
expect(itemBounds.height).not.toBe(0);
});
+ it("should emit expanded/collapsed events when toggled", async () => {
+ const page = await newE2EPage();
+ await page.setContent(html``);
+ const item = await page.find("calcite-tree-item");
+
+ const expandSpy = await page.spyOnEvent("calciteTreeItemExpand");
+ const collapseSpy = await page.spyOnEvent("calciteTreeItemCollapse");
+
+ item.setProperty("expanded", true);
+ await page.waitForChanges();
+ expect(await item.getProperty("expanded")).toBe(true);
+ expect(expandSpy).toHaveReceivedEventTimes(1);
+ expect(collapseSpy).toHaveReceivedEventTimes(0);
+
+ item.setProperty("expanded", false);
+ await page.waitForChanges();
+ expect(await item.getProperty("expanded")).toBe(false);
+ expect(expandSpy).toHaveReceivedEventTimes(1);
+ expect(collapseSpy).toHaveReceivedEventTimes(1);
+ });
+
describe("themed", () => {
describe(`selection-mode="none"`, () => {
themed(
diff --git a/packages/calcite-components/src/components/tree-item/tree-item.tsx b/packages/calcite-components/src/components/tree-item/tree-item.tsx
index 5a43d106015..ae06db6639b 100644
--- a/packages/calcite-components/src/components/tree-item/tree-item.tsx
+++ b/packages/calcite-components/src/components/tree-item/tree-item.tsx
@@ -35,13 +35,13 @@ declare global {
* @slot actions-end - A slot for adding actions to the end of the component. It is recommended to use two or fewer actions.
*/
export class TreeItem extends LitElement implements InteractiveComponent {
- // #region Static Members
+ //#region Static Members
static override styles = styles;
- // #endregion
+ //#endregion
- // #region Private Properties
+ //#region Private Properties
private actionSlotWrapper = createRef();
@@ -53,9 +53,9 @@ export class TreeItem extends LitElement implements InteractiveComponent {
private userChangedValue = false;
- // #endregion
+ //#endregion
- // #region State Properties
+ //#region State Properties
@state() private hasEndActions = false;
@@ -67,9 +67,9 @@ export class TreeItem extends LitElement implements InteractiveComponent {
*/
@state() updateAfterInitialRender = false;
- // #endregion
+ //#endregion
- // #region Public Properties
+ //#region Public Properties
/** @private */
@property({ reflect: true }) depth = -1;
@@ -77,7 +77,7 @@ export class TreeItem extends LitElement implements InteractiveComponent {
/** When `true`, interaction is prevented and the component is displayed with lower opacity. */
@property({ reflect: true }) disabled = false;
- /** When `true`, the component is expanded. */
+ /** When `true`, expands the component and its contents. */
@property({ reflect: true }) expanded = false;
/** @private */
@@ -116,16 +116,22 @@ export class TreeItem extends LitElement implements InteractiveComponent {
/** @private */
@property({ reflect: true }) selectionMode: SelectionMode;
- // #endregion
+ //#endregion
- // #region Events
+ //#region Events
/** @private */
calciteInternalTreeItemSelect = createEvent({ cancelable: false });
- // #endregion
+ /** Fires when the component's content area is collapsed. */
+ calciteTreeItemCollapse = createEvent({ cancelable: false });
- // #region Lifecycle
+ /** Fires when the component's content area is expanded. */
+ calciteTreeItemExpand = createEvent({ cancelable: false });
+
+ //#endregion
+
+ //#region Lifecycle
constructor() {
super();
@@ -147,8 +153,17 @@ export class TreeItem extends LitElement implements InteractiveComponent {
To account for this semantics change, the checks for (this.hasUpdated || value != defaultValue) was added in this method
Please refactor your code to reduce the need for this check.
Docs: https://qawebgis.esri.com/arcgis-components/?path=/docs/lumina-transition-from-stencil--docs#watching-for-property-changes */
- if (changes.has("expanded") && (this.hasUpdated || this.expanded !== false)) {
- this.updateChildTree();
+ if (changes.has("expanded")) {
+ if (this.hasUpdated || this.expanded !== false) {
+ this.updateChildTree();
+ }
+ if (this.hasUpdated) {
+ if (this.expanded) {
+ this.calciteTreeItemExpand.emit();
+ } else {
+ this.calciteTreeItemCollapse.emit();
+ }
+ }
}
if (changes.has("selected") && (this.hasUpdated || this.selected !== false)) {
@@ -168,9 +183,10 @@ export class TreeItem extends LitElement implements InteractiveComponent {
this.updateAncestorTree();
}
- // #endregion
+ //#endregion
+
+ //#region Private Methods
- // #region Private Methods
private handleSelectedChange(value: boolean): void {
if (this.selectionMode === "ancestors" && !this.userChangedValue) {
if (value) {
@@ -342,9 +358,9 @@ export class TreeItem extends LitElement implements InteractiveComponent {
}
}
- // #endregion
+ //#endregion
- // #region Rendering
+ //#region Rendering
override render(): JsxNode {
const rtl = getElementDir(this.el) === "rtl";
@@ -494,5 +510,5 @@ export class TreeItem extends LitElement implements InteractiveComponent {
);
}
- // #endregion
+ //#endregion
}