Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,18 @@ export class AccordionItem extends LitElement {

// #region Public Methods

/** Sets focus on the component. */
/**
* Sets focus on the component.
*
* @param options - When specified an optional object customizes the component's focusing process. When `preventScroll` is `true`, scrolling will not occur on the component.
Copy link
Copy Markdown
Contributor

@isaacbraun isaacbraun Jul 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just some nitpicks/ideas. Maybe a comma after "specified", and I think we can communicate the scroll behavior a bit better (and more in line with MDN). Not needed if everyone else thinks the current wording is good. Something more like:

When specified, an optional object customizes the component's focusing process. When `preventScroll` is `true`, the browser will not scroll the component into view.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good suggestion.

One downside worth mentioning is that as options are updated, we'll need to update our doc as well (e.g., upcoming focusVisible). cc @geospatialem

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jcfranco Would we support focusVisible in the future? That seems like it would go against our initiative to always display the focus?

*
* @mdn [focus(options)](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus#options)
*/
@method()
async setFocus(): Promise<void> {
async setFocus(options?: FocusOptions): Promise<void> {
return this.focusSetter(() => {
return this.headerEl;
});
}, options);
}

// #endregion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,12 +172,18 @@ export class ActionBar extends LitElement {
this.resize({ width: this.el.clientWidth, height: this.el.clientHeight });
}

/** Sets focus on the component's first focusable element. */
/**
* Sets focus on the component's first focusable element.
*
* @param options - When specified an optional object customizes the component's focusing process. When `preventScroll` is `true`, scrolling will not occur on the component.
*
* @mdn [focus(options)](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus#options)
*/
@method()
async setFocus(): Promise<void> {
async setFocus(options?: FocusOptions): Promise<void> {
return this.focusSetter(() => {
return this.el;
});
}, options);
}

//#endregion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,18 @@ export class ActionGroup extends LitElement {

//#region Public Methods

/** Sets focus on the component's first focusable element. */
/**
* Sets focus on the component's first focusable element.
*
* @param options - When specified an optional object customizes the component's focusing process. When `preventScroll` is `true`, scrolling will not occur on the component.
*
* @mdn [focus(options)](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus#options)
*/
@method()
async setFocus(): Promise<void> {
async setFocus(options?: FocusOptions): Promise<void> {
return this.focusSetter(() => {
return this.el;
});
}, options);
}

//#endregion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,12 +180,18 @@ export class ActionMenu extends LitElement {

// #region Public Methods

/** Sets focus on the component. */
/**
* Sets focus on the component.
*
* @param options - When specified an optional object customizes the component's focusing process. When `preventScroll` is `true`, scrolling will not occur on the component.
*
* @mdn [focus(options)](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus#options)
*/
@method()
async setFocus(): Promise<void> {
async setFocus(options?: FocusOptions): Promise<void> {
return this.focusSetter(() => {
return this.menuButtonEl;
});
}, options);
}

// #endregion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,18 @@ export class ActionPad extends LitElement {

//#region Public Methods

/** Sets focus on the component's first focusable element. */
/**
* Sets focus on the component's first focusable element.
*
* @param options - When specified an optional object customizes the component's focusing process. When `preventScroll` is `true`, scrolling will not occur on the component.
*
* @mdn [focus(options)](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus#options)
*/
@method()
async setFocus(): Promise<void> {
async setFocus(options?: FocusOptions): Promise<void> {
return this.focusSetter(() => {
return this.el;
});
}, options);
}

//#endregion
Expand Down
17 changes: 16 additions & 1 deletion packages/calcite-components/src/components/action/action.e2e.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
import { newE2EPage } from "@arcgis/lumina-compiler/puppeteerTesting";
import { describe, expect, it } from "vitest";
import { accessible, disabled, hidden, renders, slots, t9n, defaults, themed, reflects } from "../../tests/commonTests";
import {
accessible,
disabled,
hidden,
renders,
slots,
t9n,
defaults,
themed,
reflects,
focusable,
} from "../../tests/commonTests";
import { html } from "../../../support/formatting";
import { CSS, SLOTS } from "./resources";

Expand Down Expand Up @@ -111,6 +122,10 @@ describe("calcite-action", () => {
disabled("calcite-action");
});

describe("focusable", () => {
focusable("calcite-action");
});

describe("slots", () => {
slots("calcite-action", SLOTS);
});
Expand Down
12 changes: 9 additions & 3 deletions packages/calcite-components/src/components/action/action.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,18 @@ export class Action extends LitElement implements InteractiveComponent {

//#region Public Methods

/** Sets focus on the component. */
/**
* Sets focus on the component.
*
* @param options - When specified an optional object customizes the component's focusing process. When `preventScroll` is `true`, scrolling will not occur on the component.
*
* @mdn [focus(options)](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus#options)
*/
@method()
async setFocus(): Promise<void> {
async setFocus(options?: FocusOptions): Promise<void> {
return this.focusSetter(() => {
return this.buttonEl.value;
});
}, options);
}

//#endregion
Expand Down
10 changes: 7 additions & 3 deletions packages/calcite-components/src/components/alert/alert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -168,13 +168,17 @@ export class Alert extends LitElement implements OpenCloseComponent {
/**
* Sets focus on the component's "close" button, the first focusable item.
*
* `@returns` {Promise<void>}
* `@returns` {Promise<void>}
*
* @param options - When specified an optional object customizes the component's focusing process. When `preventScroll` is `true`, scrolling will not occur on the component.
*
* @mdn [focus(options)](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus#options)
*/
@method()
async setFocus(): Promise<void> {
async setFocus(options?: FocusOptions): Promise<void> {
return this.focusSetter(() => {
return this.el;
});
}, options);
}

//#endregion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ export class Autocomplete
* top: 0, // Specifies the number of pixels along the Y axis to scroll the window or element
* behavior: "auto" // Specifies whether the scrolling should animate smoothly (smooth), or happen instantly in a single jump (auto, the default value).
* });
* @param options - allows specific coordinates to be defined.
* @param options
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this description removed intentionally on autocomplete and dialog, but not on flow-item and panel?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unintentional. 😅 Will fix. Thanks for the catch!

* @returns - promise that resolves once the content is scrolled to.
*/
@method()
Expand All @@ -387,13 +387,16 @@ export class Autocomplete
/**
* Sets focus on the component's first focusable element.
*
* @param options - When specified an optional object customizes the component's focusing process. When `preventScroll` is `true`, scrolling will not occur on the component.
*
* @mdn [focus(options)](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus#options)
* @returns {Promise<void>}
*/
@method()
async setFocus(): Promise<void> {
async setFocus(options?: FocusOptions): Promise<void> {
return this.focusSetter(() => {
return this.referenceEl;
});
}, options);
}

//#endregion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,13 +113,16 @@ export class BlockGroup extends LitElement implements InteractiveComponent, Sort
/**
* Sets focus on the component's first focusable element.
*
* @param options - When specified an optional object customizes the component's focusing process. When `preventScroll` is `true`, scrolling will not occur on the component.
*
* @mdn [focus(options)](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus#options)
* @returns {Promise<void>}
*/
@method()
async setFocus(): Promise<void> {
async setFocus(options?: FocusOptions): Promise<void> {
return this.focusSetter(() => {
return this.el;
});
}, options);
}

// #endregion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,18 @@ export class BlockSection extends LitElement {

//#region Public Methods

/** Sets focus on the component's first tabbable element. */
/**
* Sets focus on the component's first tabbable element.
*
* @param options - When specified an optional object customizes the component's focusing process. When `preventScroll` is `true`, scrolling will not occur on the component.
*
* @mdn [focus(options)](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus#options)
*/
@method()
async setFocus(): Promise<void> {
async setFocus(options?: FocusOptions): Promise<void> {
return this.focusSetter(() => {
return this.el;
});
}, options);
}

//#endregion
Expand Down
12 changes: 9 additions & 3 deletions packages/calcite-components/src/components/block/block.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -202,12 +202,18 @@ export class Block extends LitElement implements InteractiveComponent, OpenClose

//#region Public Methods

/** Sets focus on the component's first tabbable element. */
/**
* Sets focus on the component's first tabbable element.
*
* @param options - When specified an optional object customizes the component's focusing process. When `preventScroll` is `true`, scrolling will not occur on the component.
*
* @mdn [focus(options)](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus#options)
*/
@method()
async setFocus(): Promise<void> {
async setFocus(options?: FocusOptions): Promise<void> {
return this.focusSetter(() => {
return this.el;
});
}, options);
}

//#endregion
Expand Down
16 changes: 15 additions & 1 deletion packages/calcite-components/src/components/button/button.e2e.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
// @ts-strict-ignore
import { newE2EPage, E2EElement } from "@arcgis/lumina-compiler/puppeteerTesting";
import { describe, expect, it } from "vitest";
import { accessible, defaults, disabled, hidden, HYDRATED_ATTR, labelable, t9n, themed } from "../../tests/commonTests";
import {
accessible,
defaults,
disabled,
focusable,
hidden,
HYDRATED_ATTR,
labelable,
t9n,
themed,
} from "../../tests/commonTests";
import { GlobalTestProps } from "../../tests/utils/puppeteer";
import { html } from "../../../support/formatting";
import { CSS } from "./resources";
Expand Down Expand Up @@ -172,6 +182,10 @@ describe("calcite-button", () => {
disabled("calcite-button");
});

describe("focusable", () => {
focusable("calcite-button");
});

it("should have aria-live attribute set to polite by default", async () => {
const page = await newE2EPage();
await page.setContent(`<calcite-button>Continue</calcite-button>`);
Expand Down
12 changes: 9 additions & 3 deletions packages/calcite-components/src/components/button/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -190,10 +190,16 @@ export class Button

//#region Public Methods

/** Sets focus on the component. */
/**
* Sets focus on the component.
*
* @param options - When specified an optional object customizes the component's focusing process. When `preventScroll` is `true`, scrolling will not occur on the component.
*
* @mdn [focus(options)](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus#options)
*/
@method()
async setFocus(): Promise<void> {
return this.focusSetter(() => this.childEl);
async setFocus(options?: FocusOptions): Promise<void> {
return this.focusSetter(() => this.childEl, options);
}

//#endregion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { newE2EPage } from "@arcgis/lumina-compiler/puppeteerTesting";
import { describe, expect, it } from "vitest";
import { html } from "../../../support/formatting";
import { accessible, renders, hidden, disabled, themed } from "../../tests/commonTests";
import { accessible, renders, hidden, disabled, themed, focusable } from "../../tests/commonTests";
import { createSelectedItemsAsserter } from "../../tests/utils/puppeteer";
import { CSS } from "./resources";

Expand All @@ -21,6 +21,18 @@ describe("calcite-card-group", () => {
disabled("<calcite-card-group><calcite-card></calcite-card></calcite-card-group>", { focusTarget: "none" });
});

describe("focusable", () => {
focusable(
html` <calcite-card-group>
<calcite-card label="test-label"><span slot="heading">Heading</span></calcite-card>
<calcite-card label="test-label-2"><span slot="heading">Heading</span></calcite-card>
</calcite-card-group>`,
{
focusTargetSelector: "calcite-card:first-of-type",
},
);
});

describe("is accessible in selection mode none (default)", () => {
accessible(
html`<calcite-card-group label="test-label-group">
Expand All @@ -32,7 +44,7 @@ describe("calcite-card-group", () => {

describe("is accessible in selection mode single", () => {
accessible(
html` <calcite-card-group label="test-label-group" selection-mode="single">
html`<calcite-card-group label="test-label-group" selection-mode="single">
<calcite-card label="test-label"><span slot="heading">Heading</span></calcite-card>
<calcite-card label="test-label-2"><span slot="heading">Heading</span></calcite-card>
</calcite-card-group>`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,18 @@ export class CardGroup extends LitElement implements InteractiveComponent {

// #region Public Methods

/** Sets focus on the component's first focusable element. */
/**
* Sets focus on the component's first focusable element.
*
* @param options - When specified an optional object customizes the component's focusing process. When `preventScroll` is `true`, scrolling will not occur on the component.
*
* @mdn [focus(options)](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus#options)
*/
@method()
async setFocus(): Promise<void> {
async setFocus(options?: FocusOptions): Promise<void> {
return this.focusSetter(() => {
return this.items[0];
});
}, options);
}

// #endregion
Expand Down
Loading
Loading