diff --git a/src/components/calcite-action/calcite-action.e2e.ts b/src/components/calcite-action/calcite-action.e2e.ts index 5503735e..f8269c98 100755 --- a/src/components/calcite-action/calcite-action.e2e.ts +++ b/src/components/calcite-action/calcite-action.e2e.ts @@ -43,6 +43,23 @@ describe("calcite-action", () => { expect(iconContainer).not.toBeNull(); }); + it("should have icon container with calcite-icon: after delay", async () => { + const page = await newE2EPage(); + await page.setContent(``); + + const action = await page.find("calcite-action"); + + const delay = 1; + await new Promise((resolve) => setTimeout(resolve, delay)); + + action.innerHTML = ``; + + await page.waitForChanges(); + + const iconContainer = await page.find(`calcite-action >>> .${CSS.iconContainer}`); + expect(iconContainer).not.toBeNull(); + }); + it("should have icon container with svg", async () => { const page = await newE2EPage(); await page.setContent(``); diff --git a/src/components/calcite-action/calcite-action.tsx b/src/components/calcite-action/calcite-action.tsx index a24cee60..b6d347e1 100755 --- a/src/components/calcite-action/calcite-action.tsx +++ b/src/components/calcite-action/calcite-action.tsx @@ -9,7 +9,7 @@ import { CSS } from "./resources"; import { CSS_UTILITY } from "../utils/resources"; import { getElementDir } from "../utils/dom"; -import { VNode } from "@stencil/core/internal"; +import { VNode, State } from "@stencil/core/internal"; /** * @slot - A slot for adding a `calcite-icon`. @@ -91,7 +91,29 @@ export class CalciteAction { @Element() el: HTMLCalciteActionElement; - private buttonEl: HTMLButtonElement; + @State() hasChildren = false; + + buttonEl: HTMLButtonElement; + + observer = new MutationObserver(() => this.setHasChildren()); + + // -------------------------------------------------------------------------- + // + // Lifecycle + // + // -------------------------------------------------------------------------- + + componentWillLoad(): void { + this.setHasChildren(); + } + + componentDidLoad(): void { + this.observer.observe(this.el, { childList: true, subtree: true }); + } + + componentDidUnload(): void { + this.observer.disconnect(); + } // -------------------------------------------------------------------------- // @@ -104,6 +126,16 @@ export class CalciteAction { this.buttonEl.focus(); } + // -------------------------------------------------------------------------- + // + // Private Methods + // + // -------------------------------------------------------------------------- + + setHasChildren = (): void => { + this.hasChildren = !!this.el.children?.length; + }; + // -------------------------------------------------------------------------- // // Render Methods @@ -125,12 +157,12 @@ export class CalciteAction { } renderIconContainer(): VNode { - const { el, loading, icon, scale } = this; + const { loading, icon, scale, hasChildren } = this; const iconScale = scale === "l" ? "m" : "s"; const calciteLoaderNode = loading ? : null; const calciteIconNode = icon ? : null; const iconNode = calciteLoaderNode || calciteIconNode; - const hasIconToDisplay = iconNode || el.children?.length; + const hasIconToDisplay = iconNode || hasChildren; const slotContainerNode = (
calcite-action

LTR

With text

- + -