From eb61c68762bf89f1594ce1ba3e8fbddaf5344c43 Mon Sep 17 00:00:00 2001
From: Radoslav Karaivanov
Date: Wed, 13 May 2026 06:24:14 +0300
Subject: [PATCH 1/7] feat: Invoker commands integration for components
This commit integrates invoker commands into our components,
allowing for more flexible and dynamic interactions.
The changes include updates to button components,
the addition of a new command controller,
and modifications to related stories and configurations.
---
.vscode/cspell.json | 9 +-
src/components/button/button-base.ts | 196 +++++++++++++++----
src/components/button/button.spec.ts | 148 ++++++++++++++
src/components/button/button.ts | 44 ++++-
src/components/button/icon-button.ts | 65 +++++-
src/components/common/controllers/command.ts | 85 ++++++++
stories/button.stories.ts | 91 +++++++--
stories/icon-button.stories.ts | 110 ++++++++---
tsconfig.json | 1 +
9 files changed, 651 insertions(+), 98 deletions(-)
create mode 100644 src/components/common/controllers/command.ts
diff --git a/.vscode/cspell.json b/.vscode/cspell.json
index faf1677550..c12ffbb122 100644
--- a/.vscode/cspell.json
+++ b/.vscode/cspell.json
@@ -11,6 +11,7 @@
"aria-valuenow",
"aria-valuetext",
"combobox",
+ "commandfor",
"listbox",
"listitem",
"progressbar",
@@ -32,9 +33,9 @@
"igniteui",
"slotchange",
"stylelint",
- "webcomponents"
- ],
- "ignoreRegExpList": [
- "θ"
+ "webcomponents",
+ "noopener",
+ "noreferrer"
],
+ "ignoreRegExpList": ["θ"]
}
diff --git a/src/components/button/button-base.ts b/src/components/button/button-base.ts
index e543503158..3432630373 100644
--- a/src/components/button/button-base.ts
+++ b/src/components/button/button-base.ts
@@ -1,4 +1,9 @@
-import { html, LitElement, nothing, type TemplateResult } from 'lit';
+import {
+ html,
+ LitElement,
+ type PropertyValues,
+ type TemplateResult,
+} from 'lit';
import { property, query } from 'lit/decorators.js';
import { ifDefined } from 'lit/directives/if-defined.js';
import { addKeyboardFocusRing } from '../common/controllers/focus-ring.js';
@@ -8,6 +13,7 @@ import { shadowOptions } from '../common/decorators/shadow-options.js';
import type { Constructor } from '../common/mixins/constructor.js';
import { EventEmitterMixin } from '../common//mixins/event-emitter.js';
import { partMap } from '../common/part-map.js';
+import { bindIf, getRoot, isString } from '../common/util.js';
export interface IgcButtonEventMap {
// For analyzer meta only:
@@ -17,6 +23,16 @@ export interface IgcButtonEventMap {
blur: FocusEvent;
}
+/**
+ * Abstract base class shared by `igc-button` and `igc-icon-button`.
+ *
+ * Provides common form-association behavior, link-button rendering
+ * (renders as `` when `href` is set), keyboard focus-ring management,
+ * and the Invoker Commands API (`command` / `commandfor`).
+ *
+ * Concrete subclasses must implement `_renderContent()` to supply the
+ * visual content projected inside the native `
- Show
- Hide
- Toggle
+ Show
+ Hide
+ Toggle
No internet connection. Please check your network settings.
- DismissRetry
@@ -251,7 +262,10 @@ export const CancelableClose: Story = {
>
Click "Dismiss" to see the events fire.
- Reset banner
diff --git a/stories/button.stories.ts b/stories/button.stories.ts
index 8ca4973f8d..cb192c2ead 100644
--- a/stories/button.stories.ts
+++ b/stories/button.stories.ts
@@ -100,15 +100,14 @@ const metadata: Meta = {
command: {
type: 'string',
description:
- "The command to invoke on the target element specified by `commandForElement`.\nPart of the [Invoker Commands](https://developer.mozilla.org/en-US/docs/Web/API/Invoker_Commands_API)\nAPI. Built-in values include `'show-popover'`, `'hide-popover'`,\n`'toggle-popover'`, and `'open'`. Custom commands must start with two\ndashes (e.g. `'--my-command'`).",
+ "The command to invoke on the target element specified by `commandfor`.\nPart of the [Invoker Commands](https://developer.mozilla.org/en-US/docs/Web/API/Invoker_Commands_API) API.\nCustom commands must start with two dashes (e.g. `'--my-command'`).",
control: 'text',
},
- commandForElement: {
- type: 'Element | string',
+ commandfor: {
+ type: 'string',
description:
- "The element that the button's command is associated with.\nThis can be an actual Element or a string ID of an element in the same document.\nIf this property is set, the button will dispatch its command to the specified element instead of itself.",
- options: ['Element', 'string'],
- control: { type: 'inline-radio' },
+ 'The ID of the target element for the invoker command.\nPart of the [Invoker Commands API](https://developer.mozilla.org/en-US/docs/Web/API/Invoker_Commands_API).',
+ control: 'text',
},
},
args: { variant: 'contained', type: 'button', disabled: false },
@@ -164,19 +163,16 @@ interface IgcButtonArgs {
/** When set, the button will be disabled and non-interactive. */
disabled: boolean;
/**
- * The command to invoke on the target element specified by `commandForElement`.
- * Part of the [Invoker Commands](https://developer.mozilla.org/en-US/docs/Web/API/Invoker_Commands_API)
- * API. Built-in values include `'show-popover'`, `'hide-popover'`,
- * `'toggle-popover'`, and `'open'`. Custom commands must start with two
- * dashes (e.g. `'--my-command'`).
+ * The command to invoke on the target element specified by `commandfor`.
+ * Part of the [Invoker Commands](https://developer.mozilla.org/en-US/docs/Web/API/Invoker_Commands_API) API.
+ * Custom commands must start with two dashes (e.g. `'--my-command'`).
*/
command: string;
/**
- * The element that the button's command is associated with.
- * This can be an actual Element or a string ID of an element in the same document.
- * If this property is set, the button will dispatch its command to the specified element instead of itself.
+ * The ID of the target element for the invoker command.
+ * Part of the [Invoker Commands API](https://developer.mozilla.org/en-US/docs/Web/API/Invoker_Commands_API).
*/
- commandForElement: Element | string;
+ commandfor: string;
}
type Story = StoryObj;
diff --git a/stories/dialog.stories.ts b/stories/dialog.stories.ts
index 2c548d0c97..490bd10101 100644
--- a/stories/dialog.stories.ts
+++ b/stories/dialog.stories.ts
@@ -122,18 +122,6 @@ type Story = StoryObj;
// endregion
-function getDialog(id: string) {
- return document.getElementById(id) as IgcDialogComponent;
-}
-
-function openDialog(id: string) {
- getDialog(id).show();
-}
-
-function closeDialog(id: string) {
- getDialog(id).hide();
-}
-
const authMethods = ['Basic', 'Bearer', 'Digest', 'OAuth'];
export const Default: Story = {
@@ -152,7 +140,7 @@ export const Default: Story = {
- openDialog('form-dialog')}>
+
Open form dialog
diff --git a/stories/icon-button.stories.ts b/stories/icon-button.stories.ts
index ea33fde7f7..87ad1131e5 100644
--- a/stories/icon-button.stories.ts
+++ b/stories/icon-button.stories.ts
@@ -95,15 +95,14 @@ const metadata: Meta = {
command: {
type: 'string',
description:
- "The command to invoke on the target element specified by `commandForElement`.\nPart of the [Invoker Commands](https://developer.mozilla.org/en-US/docs/Web/API/Invoker_Commands_API)\nAPI. Built-in values include `'show-popover'`, `'hide-popover'`,\n`'toggle-popover'`, and `'open'`. Custom commands must start with two\ndashes (e.g. `'--my-command'`).",
+ "The command to invoke on the target element specified by `commandfor`.\nPart of the [Invoker Commands](https://developer.mozilla.org/en-US/docs/Web/API/Invoker_Commands_API) API.\nCustom commands must start with two dashes (e.g. `'--my-command'`).",
control: 'text',
},
- commandForElement: {
- type: 'Element | string',
+ commandfor: {
+ type: 'string',
description:
- "The element that the button's command is associated with.\nThis can be an actual Element or a string ID of an element in the same document.\nIf this property is set, the button will dispatch its command to the specified element instead of itself.",
- options: ['Element', 'string'],
- control: { type: 'inline-radio' },
+ 'The ID of the target element for the invoker command.\nPart of the [Invoker Commands API](https://developer.mozilla.org/en-US/docs/Web/API/Invoker_Commands_API).',
+ control: 'text',
},
},
args: {
@@ -169,19 +168,16 @@ interface IgcIconButtonArgs {
/** When set, the button will be disabled and non-interactive. */
disabled: boolean;
/**
- * The command to invoke on the target element specified by `commandForElement`.
- * Part of the [Invoker Commands](https://developer.mozilla.org/en-US/docs/Web/API/Invoker_Commands_API)
- * API. Built-in values include `'show-popover'`, `'hide-popover'`,
- * `'toggle-popover'`, and `'open'`. Custom commands must start with two
- * dashes (e.g. `'--my-command'`).
+ * The command to invoke on the target element specified by `commandfor`.
+ * Part of the [Invoker Commands](https://developer.mozilla.org/en-US/docs/Web/API/Invoker_Commands_API) API.
+ * Custom commands must start with two dashes (e.g. `'--my-command'`).
*/
command: string;
/**
- * The element that the button's command is associated with.
- * This can be an actual Element or a string ID of an element in the same document.
- * If this property is set, the button will dispatch its command to the specified element instead of itself.
+ * The ID of the target element for the invoker command.
+ * Part of the [Invoker Commands API](https://developer.mozilla.org/en-US/docs/Web/API/Invoker_Commands_API).
*/
- commandForElement: Element | string;
+ commandfor: string;
}
type Story = StoryObj;
diff --git a/stories/nav-drawer.stories.ts b/stories/nav-drawer.stories.ts
index 223f1d5169..d76671f6ed 100644
--- a/stories/nav-drawer.stories.ts
+++ b/stories/nav-drawer.stories.ts
@@ -22,7 +22,7 @@ const metadata: Meta = {
docs: {
description: {
component:
- 'A side navigation container that provides\nquick access between views within an application.\n\n\nWhen content is provided in the `mini` slot, a compact icon-only variant is\ndisplayed alongside the main drawer.',
+ 'A side navigation container that provides\nquick access between views within an application.\n\nFor non-relative positions (`start`, `end`, `top`, `bottom`) the drawer is\nrendered as a native `