Skip to content
This repository has been archived by the owner on Jun 29, 2023. It is now read-only.

feat: setFocus on dismiss button method #740 #742

Merged
merged 12 commits into from
Jan 15, 2020
30 changes: 30 additions & 0 deletions src/components/calcite-panel/calcite-panel.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,34 @@ describe("calcite-panel", () => {
<div slot="${SLOTS.footer}">test Footer</div>
</calcite-panel>
`));

it("should focus on close button", async () => {
const page = await setUpPage("<calcite-panel dismissible>test</calcite-panel>", {
withPeerDependencies: true
});

const tagName = await page.evaluate(async () => {
const calcitePanel = document.querySelector("calcite-panel");
await calcitePanel.setFocus("dismiss-button");
const activeElement = calcitePanel.shadowRoot.activeElement;
return activeElement.tagName;
});

expect(tagName).toBe("CALCITE-ACTION");
});

it("should focus on container", async () => {
const page = await setUpPage("<calcite-panel dismissible>test</calcite-panel>", {
withPeerDependencies: true
});

const tagName = await page.evaluate(async () => {
const calcitePanel = document.querySelector("calcite-panel");
await calcitePanel.setFocus();
const activeElement = calcitePanel.shadowRoot.activeElement;
return activeElement.tagName;
});

expect(tagName).toBe("ARTICLE");
});
});
42 changes: 40 additions & 2 deletions src/components/calcite-panel/calcite-panel.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
import { Component, Element, Event, EventEmitter, Host, Prop, Watch, h } from "@stencil/core";
import {
Component,
Element,
Event,
EventEmitter,
Host,
Method,
Prop,
Watch,
h
} from "@stencil/core";
import { CSS, ICONS, SLOTS, TEXT } from "./resources";
import { getElementDir } from "../utils/dom";
import classnames from "classnames";
Expand All @@ -7,6 +17,8 @@ import { VNode } from "@stencil/core/internal";
import { CalciteScale, CalciteTheme } from "../interfaces";
import CalciteScrim from "../utils/CalciteScrim";

type FocusId = "dismiss-button";

/**
* @slot header-content - A slot for adding content in the center of the header.
* @slot header-leading-content - A slot for adding a `calcite-action` on the leading side of the header.
Expand Down Expand Up @@ -74,6 +86,10 @@ export class CalcitePanel {

@Element() el: HTMLCalcitePanelElement;

dismissButtonEl: HTMLCalciteActionElement;

containerEl: HTMLElement;

// --------------------------------------------------------------------------
//
// Events
Expand Down Expand Up @@ -102,6 +118,22 @@ export class CalcitePanel {
this.dismissed = true;
};

// --------------------------------------------------------------------------
//
// Methods
//
// --------------------------------------------------------------------------

@Method()
async setFocus(focusId?: FocusId) {
if (focusId === "dismiss-button") {
this.dismissButtonEl?.setFocus();
return;
}

this.containerEl?.focus();
}

// --------------------------------------------------------------------------
//
// Render Methods
Expand Down Expand Up @@ -129,7 +161,12 @@ export class CalcitePanel {
const { dismiss, dismissible, textClose } = this;

const dismissibleNode = dismissible ? (
<calcite-action aria-label={textClose} text={textClose} onClick={dismiss}>
<calcite-action
ref={(dismissButtonEl) => (this.dismissButtonEl = dismissButtonEl)}
aria-label={textClose}
text={textClose}
onClick={dismiss}
>
<calcite-icon scale="s" icon={ICONS.close} />
</calcite-action>
) : null;
Expand Down Expand Up @@ -193,6 +230,7 @@ export class CalcitePanel {
onKeyUp={panelKeyUpHandler}
tabIndex={dismissible ? 0 : -1}
hidden={dismissible && dismissed}
ref={(containerEl) => (this.containerEl = containerEl)}
class={classnames(CSS.container, {
[CSS_UTILITY.rtl]: rtl
})}
Expand Down
5 changes: 4 additions & 1 deletion src/demos/panel/basic.html
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ <h2>Dismissible Panel</h2>
dismissiblePanel.addEventListener("calcitePanelDismissedChange", function() {
console.log("calcitePanelDismiss event");
});
setTimeout(function() {
dismissiblePanel.setFocus("dismiss-button");
}, 3000);
</script>

<div class="panel-container" dir="rtl">
Expand All @@ -73,7 +76,7 @@ <h3>With Header Actions</h3>
</calcite-panel>

<h3>Dismissible Panel</h3>
<calcite-panel dismissible id="dismissible-panel">
<calcite-panel dismissible>
<div slot="header-content">Dismissible panel header</div>
<p>X position reversed!</p>
</calcite-panel>
Expand Down