@carbon/ibm-products-web-components 0.36.0 → 0.37.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/custom-elements.json +227 -26
- package/es/components/action-set/action-set.d.ts +109 -0
- package/es/components/action-set/action-set.d.ts.map +1 -0
- package/es/components/action-set/action-set.js +275 -0
- package/es/components/action-set/action-set.js.map +1 -0
- package/es/components/action-set/action-set.scss.js +15 -0
- package/es/components/action-set/action-set.scss.js.map +1 -0
- package/es/components/action-set/index.d.ts +11 -0
- package/es/components/action-set/index.d.ts.map +1 -0
- package/es/components/action-set/index.js +8 -0
- package/es/components/big-number/big-number-skeleton.js +1 -1
- package/es/components/big-number/big-number.js +1 -1
- package/es/components/checklist/checklist-icon.js +1 -1
- package/es/components/checklist/checklist-item.js +1 -1
- package/es/components/checklist/checklist.js +1 -1
- package/es/components/coachmark/coachmark-tagline/coachmark-tagline.d.ts +1 -0
- package/es/components/coachmark/coachmark-tagline/coachmark-tagline.d.ts.map +1 -1
- package/es/components/coachmark/coachmark-tagline/coachmark-tagline.js +4 -1
- package/es/components/coachmark/coachmark-tagline/coachmark-tagline.js.map +1 -1
- package/es/components/coachmark/coachmark-tagline/coachmark-tagline.scss.js +1 -1
- package/es/components/coachmark/coachmark-tagline/coachmark-tagline.scss.js.map +1 -1
- package/es/components/coachmark/coachmark.d.ts +5 -1
- package/es/components/coachmark/coachmark.d.ts.map +1 -1
- package/es/components/coachmark/coachmark.js +10 -5
- package/es/components/coachmark/coachmark.js.map +1 -1
- package/es/components/guide-banner/guide-banner.js +2 -2
- package/es/components/interstitial-screen/interstitial-screen-body.js +1 -1
- package/es/components/interstitial-screen/interstitial-screen-body.scss.js +1 -1
- package/es/components/interstitial-screen/interstitial-screen-body.scss.js.map +1 -1
- package/es/components/interstitial-screen/interstitial-screen-footer.d.ts +1 -0
- package/es/components/interstitial-screen/interstitial-screen-footer.d.ts.map +1 -1
- package/es/components/interstitial-screen/interstitial-screen-footer.js +20 -19
- package/es/components/interstitial-screen/interstitial-screen-footer.js.map +1 -1
- package/es/components/interstitial-screen/interstitial-screen-footer.scss.js +1 -1
- package/es/components/interstitial-screen/interstitial-screen-footer.scss.js.map +1 -1
- package/es/components/interstitial-screen/interstitial-screen-header.scss.js +1 -1
- package/es/components/interstitial-screen/interstitial-screen.scss.js +1 -1
- package/es/components/notification-panel/notification-panel.js +2 -2
- package/es/components/notification-panel/notification.js +1 -1
- package/es/components/options-tile/options-tile.js +2 -2
- package/es/components/page-header/page-header-breadcrumb.js +1 -1
- package/es/components/page-header/page-header-content.js +1 -1
- package/es/components/page-header/page-header-scroller.js +2 -2
- package/es/components/side-panel/side-panel.js +2 -2
- package/es/components/tearsheet/tearsheet.js +2 -2
- package/es/components/tearsheet-preview/tearsheet-scroller.js +2 -2
- package/es/components/truncated-text/truncated-text.js +1 -1
- package/es/components/user-avatar/user-avatar.js +1 -1
- package/es/index.d.ts +1 -0
- package/es/index.d.ts.map +1 -1
- package/es/index.js +2 -1
- package/es/package.js +1 -1
- package/es-custom/components/action-set/action-set.js +275 -0
- package/es-custom/components/action-set/action-set.js.map +1 -0
- package/es-custom/components/action-set/action-set.scss.js +15 -0
- package/es-custom/components/action-set/action-set.scss.js.map +1 -0
- package/es-custom/components/action-set/index.js +8 -0
- package/es-custom/components/big-number/big-number-skeleton.js +1 -1
- package/es-custom/components/big-number/big-number.js +1 -1
- package/es-custom/components/checklist/checklist-icon.js +1 -1
- package/es-custom/components/checklist/checklist-item.js +1 -1
- package/es-custom/components/checklist/checklist.js +1 -1
- package/es-custom/components/coachmark/coachmark-tagline/coachmark-tagline.js +4 -1
- package/es-custom/components/coachmark/coachmark-tagline/coachmark-tagline.js.map +1 -1
- package/es-custom/components/coachmark/coachmark-tagline/coachmark-tagline.scss.js +1 -1
- package/es-custom/components/coachmark/coachmark-tagline/coachmark-tagline.scss.js.map +1 -1
- package/es-custom/components/coachmark/coachmark.js +10 -5
- package/es-custom/components/coachmark/coachmark.js.map +1 -1
- package/es-custom/components/guide-banner/guide-banner.js +2 -2
- package/es-custom/components/interstitial-screen/interstitial-screen-body.js +1 -1
- package/es-custom/components/interstitial-screen/interstitial-screen-body.scss.js +1 -1
- package/es-custom/components/interstitial-screen/interstitial-screen-body.scss.js.map +1 -1
- package/es-custom/components/interstitial-screen/interstitial-screen-footer.js +20 -19
- package/es-custom/components/interstitial-screen/interstitial-screen-footer.js.map +1 -1
- package/es-custom/components/interstitial-screen/interstitial-screen-footer.scss.js +1 -1
- package/es-custom/components/interstitial-screen/interstitial-screen-footer.scss.js.map +1 -1
- package/es-custom/components/interstitial-screen/interstitial-screen-header.scss.js +1 -1
- package/es-custom/components/interstitial-screen/interstitial-screen.scss.js +1 -1
- package/es-custom/components/notification-panel/notification-panel.js +2 -2
- package/es-custom/components/notification-panel/notification.js +1 -1
- package/es-custom/components/options-tile/options-tile.js +2 -2
- package/es-custom/components/page-header/page-header-breadcrumb.js +1 -1
- package/es-custom/components/page-header/page-header-content.js +1 -1
- package/es-custom/components/page-header/page-header-scroller.js +2 -2
- package/es-custom/components/side-panel/side-panel.js +2 -2
- package/es-custom/components/tearsheet/tearsheet.js +2 -2
- package/es-custom/components/tearsheet-preview/tearsheet-scroller.js +2 -2
- package/es-custom/components/truncated-text/truncated-text.js +1 -1
- package/es-custom/components/user-avatar/user-avatar.js +1 -1
- package/es-custom/index.js +2 -1
- package/es-custom/package.js +1 -1
- package/lib/components/action-set/action-set.d.ts +109 -0
- package/lib/components/action-set/action-set.d.ts.map +1 -0
- package/lib/components/action-set/index.d.ts +11 -0
- package/lib/components/action-set/index.d.ts.map +1 -0
- package/lib/components/coachmark/coachmark-tagline/coachmark-tagline.d.ts +1 -0
- package/lib/components/coachmark/coachmark-tagline/coachmark-tagline.d.ts.map +1 -1
- package/lib/components/coachmark/coachmark.d.ts +5 -1
- package/lib/components/coachmark/coachmark.d.ts.map +1 -1
- package/lib/components/interstitial-screen/interstitial-screen-footer.d.ts +1 -0
- package/lib/components/interstitial-screen/interstitial-screen-footer.d.ts.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/package.json +4 -4
- package/scss/components/action-set/action-set.scss +71 -0
- package/scss/components/coachmark/coachmark-tagline/coachmark-tagline.scss +18 -0
- package/scss/components/interstitial-screen/interstitial-screen-body.scss +6 -0
- package/scss/components/interstitial-screen/interstitial-screen-footer.scss +34 -6
- package/telemetry.yml +11 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
*
|
|
4
|
+
* Copyright IBM Corp. 2026
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
7
|
+
* LICENSE file in the root directory of this source tree.
|
|
8
|
+
*/
|
|
9
|
+
import { LitElement } from 'lit';
|
|
10
|
+
import CDSButton from '@carbon/web-components/es/components/button/button.js';
|
|
11
|
+
import '@carbon/web-components/es/components/button/index.js';
|
|
12
|
+
export declare const ButtonSizes: readonly ["sm", "md", "lg", "xl", "2xl"];
|
|
13
|
+
export type ButtonSize = (typeof ButtonSizes)[number];
|
|
14
|
+
export type ButtonKind = 'primary' | 'secondary' | 'tertiary' | 'danger' | 'ghost' | 'danger--ghost';
|
|
15
|
+
/**
|
|
16
|
+
* Action button configuration that extends CDSButton properties.
|
|
17
|
+
* Includes all standard button attributes plus custom action-specific properties.
|
|
18
|
+
*/
|
|
19
|
+
export interface ActionButton extends Partial<Omit<CDSButton, 'kind'>> {
|
|
20
|
+
kind?: ButtonKind;
|
|
21
|
+
label?: string;
|
|
22
|
+
loading?: boolean;
|
|
23
|
+
onClick?: (event: Event) => void;
|
|
24
|
+
[key: string]: any;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Action Set component - A specialized button set with validation and ordering logic.
|
|
28
|
+
* Extends Carbon's button-set with additional features for action buttons.
|
|
29
|
+
*
|
|
30
|
+
* @element c4p-action-set
|
|
31
|
+
* @slot - Slot for cds-button elements (used when actions prop is not provided)
|
|
32
|
+
*/
|
|
33
|
+
export declare class CDSActionSet extends LitElement {
|
|
34
|
+
/**
|
|
35
|
+
* Number of slotted buttons (computed internally).
|
|
36
|
+
*/
|
|
37
|
+
private _slottedButtonCount;
|
|
38
|
+
/**
|
|
39
|
+
* Computed property: `true` if the buttons are currently stacked.
|
|
40
|
+
* This is derived from size, disableStacking, and button count.
|
|
41
|
+
*/
|
|
42
|
+
get stacked(): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* The size of buttons to use for the actions.
|
|
45
|
+
*/
|
|
46
|
+
buttonSize?: ButtonSize;
|
|
47
|
+
/**
|
|
48
|
+
* The size of the action set. Different button arrangements are used at
|
|
49
|
+
* different sizes, to make best use of the available space.
|
|
50
|
+
*/
|
|
51
|
+
size: ButtonSize;
|
|
52
|
+
/**
|
|
53
|
+
* When true, prevents automatic stacking of buttons even when size would
|
|
54
|
+
* normally trigger stacking (e.g., 'sm' size or 'md' with 3+ actions).
|
|
55
|
+
* Buttons will remain in a horizontal layout.
|
|
56
|
+
*/
|
|
57
|
+
disableStacking: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Array of action button configurations. When provided, buttons will be
|
|
60
|
+
* rendered internally instead of using slotted content.
|
|
61
|
+
*/
|
|
62
|
+
actions: ActionButton[];
|
|
63
|
+
static styles: any;
|
|
64
|
+
/**
|
|
65
|
+
* Applies common button styling (size, classes, expressive attribute)
|
|
66
|
+
* @private
|
|
67
|
+
*/
|
|
68
|
+
private _applyButtonStyles;
|
|
69
|
+
/**
|
|
70
|
+
* Processes actions: validates, determines stacking, and sorts
|
|
71
|
+
* @private
|
|
72
|
+
*/
|
|
73
|
+
private _processActions;
|
|
74
|
+
/**
|
|
75
|
+
* Handler for @slotchange, processes and orders buttons based on ActionSet logic
|
|
76
|
+
*
|
|
77
|
+
* @private
|
|
78
|
+
*/
|
|
79
|
+
protected _handleSlotChange(event: Event): void;
|
|
80
|
+
/**
|
|
81
|
+
* Reorders the button elements in the DOM based on the sorted actions
|
|
82
|
+
* and applies appropriate styling
|
|
83
|
+
*
|
|
84
|
+
* @private
|
|
85
|
+
*/
|
|
86
|
+
private _reorderButtons;
|
|
87
|
+
/**
|
|
88
|
+
* When a button within the action-set is focused, hide the margin on both sides
|
|
89
|
+
* of the focused button, by applying the appropriate styles to its sibling
|
|
90
|
+
*
|
|
91
|
+
* @private
|
|
92
|
+
*/
|
|
93
|
+
private _hideSiblingMargin;
|
|
94
|
+
connectedCallback(): void;
|
|
95
|
+
disconnectedCallback(): void;
|
|
96
|
+
/**
|
|
97
|
+
* Renders buttons from the actions prop
|
|
98
|
+
* @private
|
|
99
|
+
*/
|
|
100
|
+
private _renderActionsFromProp;
|
|
101
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
102
|
+
}
|
|
103
|
+
declare global {
|
|
104
|
+
interface HTMLElementTagNameMap {
|
|
105
|
+
'c4p-action-set': CDSActionSet;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
export default CDSActionSet;
|
|
109
|
+
//# sourceMappingURL=action-set.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action-set.d.ts","sourceRoot":"","sources":["../../../src/components/action-set/action-set.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAQ,UAAU,EAAE,MAAM,KAAK,CAAC;AAOvC,OAAO,SAAS,MAAM,uDAAuD,CAAC;AAC9E,OAAO,sDAAsD,CAAC;AAK9D,eAAO,MAAM,WAAW,0CAA2C,CAAC;AACpE,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtD,MAAM,MAAM,UAAU,GAClB,SAAS,GACT,WAAW,GACX,UAAU,GACV,QAAQ,GACR,OAAO,GACP,eAAe,CAAC;AAEpB;;;GAGG;AACH,MAAM,WAAW,YAAa,SAAQ,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAEpE,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAGjC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AA6GD;;;;;;GAMG;AACH,qBACa,YAAa,SAAQ,UAAU;IAC1C;;OAEG;IAEH,OAAO,CAAC,mBAAmB,CAAK;IAEhC;;;OAGG;IACH,IAAI,OAAO,IAAI,OAAO,CAGrB;IAED;;OAEG;IAEH,UAAU,CAAC,EAAE,UAAU,CAAC;IAExB;;;OAGG;IAEH,IAAI,EAAE,UAAU,CAAQ;IAExB;;;;OAIG;IAEH,eAAe,EAAE,OAAO,CAAS;IAEjC;;;OAGG;IAEH,OAAO,EAAE,YAAY,EAAE,CAAM;IAE7B,MAAM,CAAC,MAAM,MAAU;IAEvB;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAc1B;;;OAGG;IACH,OAAO,CAAC,eAAe;IAoBvB;;;;OAIG;IACH,SAAS,CAAC,iBAAiB,CAAC,KAAK,EAAE,KAAK;IA6CxC;;;;;OAKG;IACH,OAAO,CAAC,eAAe;IAmBvB;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB,CA+BxB;IAEF,iBAAiB;IAMjB,oBAAoB;IAMpB;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IA8D9B,MAAM;CAyCP;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,gBAAgB,EAAE,YAAY,CAAC;KAChC;CACF;AAED,eAAe,YAAY,CAAC"}
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2020, 2026
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { carbonPrefix, prefix } from "../../globals/settings.js";
|
|
9
|
+
import action_set_default$1 from "./action-set.scss.js";
|
|
10
|
+
import pconsole_default from "../../globals/internal/pconsole.js";
|
|
11
|
+
import { __decorate } from "../../_virtual/_@oxc-project_runtime@0.112.0/helpers/decorate.js";
|
|
12
|
+
import { classMap } from "lit/directives/class-map.js";
|
|
13
|
+
import { LitElement, html } from "lit";
|
|
14
|
+
import { property, state } from "lit/decorators.js";
|
|
15
|
+
import { ref } from "lit/directives/ref.js";
|
|
16
|
+
import { carbonElement } from "@carbon/web-components/es/globals/decorators/carbon-element";
|
|
17
|
+
import "@carbon/web-components/es/components/button/index.js";
|
|
18
|
+
|
|
19
|
+
//#region src/components/action-set/action-set.ts
|
|
20
|
+
/**
|
|
21
|
+
* @license
|
|
22
|
+
*
|
|
23
|
+
* Copyright IBM Corp. 2026
|
|
24
|
+
*
|
|
25
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
26
|
+
* LICENSE file in the root directory of this source tree.
|
|
27
|
+
*/
|
|
28
|
+
const blockClass = `${prefix}--action-set`;
|
|
29
|
+
const ButtonSizes = [
|
|
30
|
+
"sm",
|
|
31
|
+
"md",
|
|
32
|
+
"lg",
|
|
33
|
+
"xl",
|
|
34
|
+
"2xl"
|
|
35
|
+
];
|
|
36
|
+
const defaultKind = "primary";
|
|
37
|
+
/**
|
|
38
|
+
* Determines if buttons should be stacked based on size and number of actions
|
|
39
|
+
*/
|
|
40
|
+
const willStack = (size, numberOfActions) => size === "sm" || size === "md" && numberOfActions > 2;
|
|
41
|
+
/**
|
|
42
|
+
* Returns the order priority for a button kind
|
|
43
|
+
* Lower numbers appear first (or last when stacking)
|
|
44
|
+
*/
|
|
45
|
+
const buttonOrder = (kind) => ({
|
|
46
|
+
ghost: 1,
|
|
47
|
+
"danger--ghost": 2,
|
|
48
|
+
tertiary: 3,
|
|
49
|
+
danger: 5,
|
|
50
|
+
primary: 6
|
|
51
|
+
})[kind] ?? 4;
|
|
52
|
+
/**
|
|
53
|
+
* Sorts actions based on button kind and stacking mode
|
|
54
|
+
* When not stacking: ghost first, primary last
|
|
55
|
+
* When stacking: primary first, ghost last
|
|
56
|
+
*/
|
|
57
|
+
const sortActions = (actions, stacking) => {
|
|
58
|
+
const sortedActions = [...actions];
|
|
59
|
+
sortedActions.sort((action1, action2) => (buttonOrder(action1.kind || defaultKind) - buttonOrder(action2.kind || defaultKind)) * (stacking ? -1 : 1));
|
|
60
|
+
return sortedActions;
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Validates action set configuration and returns problems
|
|
64
|
+
*/
|
|
65
|
+
const validateActionSet = (actions, size) => {
|
|
66
|
+
if (!actions || actions.length === 0) return [];
|
|
67
|
+
const problems = [];
|
|
68
|
+
const stacking = willStack(size, actions.length);
|
|
69
|
+
const countActions = (kind) => actions.filter((action) => (action.kind || defaultKind) === kind).length;
|
|
70
|
+
const primaryActions = countActions("primary");
|
|
71
|
+
const secondaryActions = countActions("secondary");
|
|
72
|
+
const tertiaryActions = countActions("tertiary");
|
|
73
|
+
const dangerActions = countActions("danger");
|
|
74
|
+
const ghostActions = countActions("ghost") + countActions("danger--ghost");
|
|
75
|
+
if (stacking && actions.length > 3) problems.push("you cannot have more than three actions in this size of ActionSet");
|
|
76
|
+
if (actions.length > 4) problems.push("you cannot have more than four actions in an ActionSet");
|
|
77
|
+
if (primaryActions > 1) problems.push("you cannot have more than one 'primary' action in an ActionSet");
|
|
78
|
+
if (ghostActions > 1) problems.push("you cannot have more than one 'ghost' action in an ActionSet");
|
|
79
|
+
if (stacking && actions.length > 1 && ghostActions > 0) problems.push("you cannot have a 'ghost' button in conjunction with other action types in this size of ActionSet");
|
|
80
|
+
if (actions.length > primaryActions + secondaryActions + tertiaryActions + dangerActions + ghostActions) problems.push("you can only have 'primary', 'danger', 'secondary', 'tertiary', 'ghost' and 'danger--ghost' buttons in an ActionSet");
|
|
81
|
+
return problems;
|
|
82
|
+
};
|
|
83
|
+
let CDSActionSet = class CDSActionSet extends LitElement {
|
|
84
|
+
constructor(..._args) {
|
|
85
|
+
super(..._args);
|
|
86
|
+
this._slottedButtonCount = 0;
|
|
87
|
+
this.size = "md";
|
|
88
|
+
this.disableStacking = false;
|
|
89
|
+
this.actions = [];
|
|
90
|
+
this._hideSiblingMargin = () => {
|
|
91
|
+
let items = [];
|
|
92
|
+
const slot = this.shadowRoot?.querySelector("slot");
|
|
93
|
+
if (slot) items = slot.assignedElements().filter((el) => el.tagName.toLowerCase() === `${carbonPrefix}-button`);
|
|
94
|
+
if (items.length === 0 && this.shadowRoot) items = Array.from(this.shadowRoot.querySelectorAll(`${carbonPrefix}-button`));
|
|
95
|
+
if (items.length === 0) return;
|
|
96
|
+
const focusedIndex = items.findIndex((el) => el.matches(":focus-within"));
|
|
97
|
+
items.forEach((el, idx) => {
|
|
98
|
+
const shouldHide = focusedIndex >= 0 && (idx === focusedIndex || idx === focusedIndex + 1);
|
|
99
|
+
el.toggleAttribute("hide-margin", shouldHide);
|
|
100
|
+
});
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Computed property: `true` if the buttons are currently stacked.
|
|
105
|
+
* This is derived from size, disableStacking, and button count.
|
|
106
|
+
*/
|
|
107
|
+
get stacked() {
|
|
108
|
+
const buttonCount = this.actions?.length || this._slottedButtonCount;
|
|
109
|
+
return this.disableStacking ? false : willStack(this.size, buttonCount);
|
|
110
|
+
}
|
|
111
|
+
static {
|
|
112
|
+
this.styles = action_set_default$1;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Applies common button styling (size, classes, expressive attribute)
|
|
116
|
+
* @private
|
|
117
|
+
*/
|
|
118
|
+
_applyButtonStyles(button, kind) {
|
|
119
|
+
if (this.buttonSize) button.setAttribute("size", this.buttonSize);
|
|
120
|
+
button.classList.add(`${blockClass}__action-button`);
|
|
121
|
+
if (kind === "ghost" || kind === "danger--ghost") button.classList.add(`${blockClass}__action-button--ghost`);
|
|
122
|
+
button.setAttribute("is-expressive", "true");
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Processes actions: validates, determines stacking, and sorts
|
|
126
|
+
* @private
|
|
127
|
+
*/
|
|
128
|
+
_processActions(actions) {
|
|
129
|
+
const problems = validateActionSet(actions, this.size);
|
|
130
|
+
const stacking = this.disableStacking ? false : willStack(this.size, actions.length);
|
|
131
|
+
const sortedActions = sortActions(actions, stacking);
|
|
132
|
+
if (problems.length > 0) pconsole_default.warn(`Invalid actions in ActionSet: ${problems.join(", and ")}.`);
|
|
133
|
+
return {
|
|
134
|
+
sortedActions,
|
|
135
|
+
stacking,
|
|
136
|
+
problems
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Handler for @slotchange, processes and orders buttons based on ActionSet logic
|
|
141
|
+
*
|
|
142
|
+
* @private
|
|
143
|
+
*/
|
|
144
|
+
_handleSlotChange(event) {
|
|
145
|
+
const childItems = event.target.assignedNodes().filter((elem) => elem.matches !== void 0 ? elem.matches(`${carbonPrefix}-button`) : false);
|
|
146
|
+
if (childItems.length === 0) return;
|
|
147
|
+
const actions = childItems.map((button) => {
|
|
148
|
+
const kind = button.getAttribute("kind");
|
|
149
|
+
const disabled = button.hasAttribute("disabled");
|
|
150
|
+
const label = button.textContent?.trim() || "";
|
|
151
|
+
return {
|
|
152
|
+
kind: kind || "primary",
|
|
153
|
+
disabled,
|
|
154
|
+
label
|
|
155
|
+
};
|
|
156
|
+
});
|
|
157
|
+
const { sortedActions } = this._processActions(actions);
|
|
158
|
+
this._slottedButtonCount = childItems.length;
|
|
159
|
+
this._reorderButtons(childItems, sortedActions);
|
|
160
|
+
const update = new CustomEvent(`${prefix}-action-set-update`, {
|
|
161
|
+
bubbles: true,
|
|
162
|
+
cancelable: true,
|
|
163
|
+
composed: true
|
|
164
|
+
});
|
|
165
|
+
this.dispatchEvent(update);
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Reorders the button elements in the DOM based on the sorted actions
|
|
169
|
+
* and applies appropriate styling
|
|
170
|
+
*
|
|
171
|
+
* @private
|
|
172
|
+
*/
|
|
173
|
+
_reorderButtons(buttons, sortedActions) {
|
|
174
|
+
const buttonMap = /* @__PURE__ */ new Map();
|
|
175
|
+
buttons.forEach((button) => {
|
|
176
|
+
const label = button.textContent?.trim() || "";
|
|
177
|
+
buttonMap.set(label, button);
|
|
178
|
+
});
|
|
179
|
+
sortedActions.forEach((action) => {
|
|
180
|
+
const button = buttonMap.get(action.label || "");
|
|
181
|
+
if (button) this._applyButtonStyles(button, action.kind);
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
connectedCallback() {
|
|
185
|
+
super.connectedCallback();
|
|
186
|
+
this.addEventListener("focusin", this._hideSiblingMargin);
|
|
187
|
+
this.addEventListener("focusout", this._hideSiblingMargin);
|
|
188
|
+
}
|
|
189
|
+
disconnectedCallback() {
|
|
190
|
+
super.disconnectedCallback();
|
|
191
|
+
this.removeEventListener("focusin", this._hideSiblingMargin);
|
|
192
|
+
this.removeEventListener("focusout", this._hideSiblingMargin);
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Renders buttons from the actions prop
|
|
196
|
+
* @private
|
|
197
|
+
*/
|
|
198
|
+
_renderActionsFromProp() {
|
|
199
|
+
if (!this.actions || this.actions.length === 0) return null;
|
|
200
|
+
const { sortedActions } = this._processActions(this.actions);
|
|
201
|
+
return sortedActions.map((action) => {
|
|
202
|
+
const { kind = "primary", label = "", disabled = false, loading = false, onClick, class: customClass, ...rest } = action;
|
|
203
|
+
const buttonClasses = classMap({
|
|
204
|
+
[`${blockClass}__action-button`]: true,
|
|
205
|
+
[`${blockClass}__action-button--ghost`]: kind === "ghost" || kind === "danger--ghost",
|
|
206
|
+
...customClass ? { [customClass]: true } : {}
|
|
207
|
+
});
|
|
208
|
+
const buttonRef = (el) => {
|
|
209
|
+
if (el && rest) Object.entries(rest).forEach(([key, value]) => {
|
|
210
|
+
if (value !== void 0 && value !== null) if (typeof value === "boolean") if (value) el.setAttribute(key, "");
|
|
211
|
+
else el.removeAttribute(key);
|
|
212
|
+
else el.setAttribute(key, String(value));
|
|
213
|
+
});
|
|
214
|
+
};
|
|
215
|
+
return html`
|
|
216
|
+
<cds-button
|
|
217
|
+
${ref(buttonRef)}
|
|
218
|
+
class="${buttonClasses}"
|
|
219
|
+
kind="${kind}"
|
|
220
|
+
size="${this.buttonSize}"
|
|
221
|
+
?disabled="${disabled || loading}"
|
|
222
|
+
is-expressive="true"
|
|
223
|
+
@click="${typeof onClick === "function" ? onClick : () => {}}"
|
|
224
|
+
>
|
|
225
|
+
${label}
|
|
226
|
+
</cds-button>
|
|
227
|
+
`;
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
render() {
|
|
231
|
+
const { actions, _slottedButtonCount, stacked } = this;
|
|
232
|
+
const buttonCount = actions?.length || _slottedButtonCount;
|
|
233
|
+
const defaultClasses = {
|
|
234
|
+
[blockClass]: true,
|
|
235
|
+
[`${blockClass}--row-single`]: !stacked && buttonCount === 1,
|
|
236
|
+
[`${blockClass}--row-double`]: !stacked && buttonCount === 2,
|
|
237
|
+
[`${blockClass}--row-triple`]: !stacked && buttonCount === 3,
|
|
238
|
+
[`${blockClass}--row-quadruple`]: !stacked && buttonCount >= 4,
|
|
239
|
+
[`${blockClass}--stacking`]: stacked,
|
|
240
|
+
[`${blockClass}--${this.size}`]: true
|
|
241
|
+
};
|
|
242
|
+
if (actions && actions.length > 0) return html`<div
|
|
243
|
+
class="${classMap({
|
|
244
|
+
...defaultClasses,
|
|
245
|
+
[`${carbonPrefix}--btn-set--stacked`]: stacked,
|
|
246
|
+
[`${carbonPrefix}--btn-set`]: true
|
|
247
|
+
})}"
|
|
248
|
+
part="action-set"
|
|
249
|
+
role="list"
|
|
250
|
+
>
|
|
251
|
+
${this._renderActionsFromProp()}
|
|
252
|
+
</div>`;
|
|
253
|
+
return html`<div class="${classMap({
|
|
254
|
+
...defaultClasses,
|
|
255
|
+
[`${carbonPrefix}--btn-set--stacked`]: stacked,
|
|
256
|
+
[`${carbonPrefix}--btn-set`]: true
|
|
257
|
+
})}" part="action-set" role="list">
|
|
258
|
+
<slot @slotchange="${this._handleSlotChange}"></slot>
|
|
259
|
+
</div>`;
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
__decorate([state()], CDSActionSet.prototype, "_slottedButtonCount", void 0);
|
|
263
|
+
__decorate([property({ attribute: "button-size" })], CDSActionSet.prototype, "buttonSize", void 0);
|
|
264
|
+
__decorate([property()], CDSActionSet.prototype, "size", void 0);
|
|
265
|
+
__decorate([property({
|
|
266
|
+
type: Boolean,
|
|
267
|
+
attribute: "disable-stacking"
|
|
268
|
+
})], CDSActionSet.prototype, "disableStacking", void 0);
|
|
269
|
+
__decorate([property({ type: Array })], CDSActionSet.prototype, "actions", void 0);
|
|
270
|
+
CDSActionSet = __decorate([carbonElement(`${prefix}-action-set`)], CDSActionSet);
|
|
271
|
+
var action_set_default = CDSActionSet;
|
|
272
|
+
|
|
273
|
+
//#endregion
|
|
274
|
+
export { ButtonSizes, CDSActionSet, action_set_default as default };
|
|
275
|
+
//# sourceMappingURL=action-set.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action-set.js","names":["styles","customElement"],"sources":["../../../src/components/action-set/action-set.ts"],"sourcesContent":["/**\n * @license\n *\n * Copyright IBM Corp. 2026\n *\n * This source code is licensed under the Apache-2.0 license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport { classMap } from 'lit/directives/class-map.js';\nimport { html, LitElement } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { ref } from 'lit/directives/ref.js';\nimport { prefix, carbonPrefix } from '../../globals/settings';\nimport { carbonElement as customElement } from '@carbon/web-components/es/globals/decorators/carbon-element';\nimport styles from './action-set.scss?lit';\nimport pconsole from '../../globals/internal/pconsole';\nimport CDSButton from '@carbon/web-components/es/components/button/button.js';\nimport '@carbon/web-components/es/components/button/index.js';\n\nconst blockClass = `${prefix}--action-set`;\n\n// Type definitions\nexport const ButtonSizes = ['sm', 'md', 'lg', 'xl', '2xl'] as const;\nexport type ButtonSize = (typeof ButtonSizes)[number];\n\nexport type ButtonKind =\n | 'primary'\n | 'secondary'\n | 'tertiary'\n | 'danger'\n | 'ghost'\n | 'danger--ghost';\n\n/**\n * Action button configuration that extends CDSButton properties.\n * Includes all standard button attributes plus custom action-specific properties.\n */\nexport interface ActionButton extends Partial<Omit<CDSButton, 'kind'>> {\n // Action-specific properties (override CDSButton types where needed)\n kind?: ButtonKind;\n label?: string;\n loading?: boolean;\n onClick?: (event: Event) => void;\n\n // Allow any other HTML attributes or custom properties\n [key: string]: any;\n}\n\nconst defaultKind: ButtonKind = 'primary';\n\n/**\n * Determines if buttons should be stacked based on size and number of actions\n */\nconst willStack = (size: ButtonSize, numberOfActions: number): boolean =>\n size === 'sm' || (size === 'md' && numberOfActions > 2);\n\n/**\n * Returns the order priority for a button kind\n * Lower numbers appear first (or last when stacking)\n */\nconst buttonOrder = (kind: ButtonKind): number =>\n ({\n ghost: 1,\n 'danger--ghost': 2,\n tertiary: 3,\n danger: 5,\n primary: 6,\n })[kind] ?? 4;\n\n/**\n * Sorts actions based on button kind and stacking mode\n * When not stacking: ghost first, primary last\n * When stacking: primary first, ghost last\n */\nconst sortActions = (\n actions: ActionButton[],\n stacking: boolean\n): ActionButton[] => {\n const sortedActions = [...actions];\n sortedActions.sort(\n (action1, action2) =>\n (buttonOrder(action1.kind || defaultKind) -\n buttonOrder(action2.kind || defaultKind)) *\n (stacking ? -1 : 1)\n );\n return sortedActions;\n};\n\n/**\n * Validates action set configuration and returns problems\n */\nconst validateActionSet = (\n actions: ActionButton[],\n size: ButtonSize\n): string[] => {\n if (!actions || actions.length === 0) {\n return [];\n }\n\n const problems: string[] = [];\n const stacking = willStack(size, actions.length);\n\n const countActions = (kind: ButtonKind): number =>\n actions.filter((action) => (action.kind || defaultKind) === kind).length;\n\n const primaryActions = countActions('primary');\n const secondaryActions = countActions('secondary');\n const tertiaryActions = countActions('tertiary');\n const dangerActions = countActions('danger');\n const ghostActions = countActions('ghost') + countActions('danger--ghost');\n\n if (stacking && actions.length > 3) {\n problems.push(\n 'you cannot have more than three actions in this size of ActionSet'\n );\n }\n\n if (actions.length > 4) {\n problems.push('you cannot have more than four actions in an ActionSet');\n }\n\n if (primaryActions > 1) {\n problems.push(\n \"you cannot have more than one 'primary' action in an ActionSet\"\n );\n }\n\n if (ghostActions > 1) {\n problems.push(\n \"you cannot have more than one 'ghost' action in an ActionSet\"\n );\n }\n\n if (stacking && actions.length > 1 && ghostActions > 0) {\n problems.push(\n \"you cannot have a 'ghost' button in conjunction with other action types in this size of ActionSet\"\n );\n }\n\n if (\n actions.length >\n primaryActions +\n secondaryActions +\n tertiaryActions +\n dangerActions +\n ghostActions\n ) {\n problems.push(\n \"you can only have 'primary', 'danger', 'secondary', 'tertiary', 'ghost' and 'danger--ghost' buttons in an ActionSet\"\n );\n }\n\n return problems;\n};\n\n/**\n * Action Set component - A specialized button set with validation and ordering logic.\n * Extends Carbon's button-set with additional features for action buttons.\n *\n * @element c4p-action-set\n * @slot - Slot for cds-button elements (used when actions prop is not provided)\n */\n@customElement(`${prefix}-action-set`)\nexport class CDSActionSet extends LitElement {\n /**\n * Number of slotted buttons (computed internally).\n */\n @state()\n private _slottedButtonCount = 0;\n\n /**\n * Computed property: `true` if the buttons are currently stacked.\n * This is derived from size, disableStacking, and button count.\n */\n get stacked(): boolean {\n const buttonCount = this.actions?.length || this._slottedButtonCount;\n return this.disableStacking ? false : willStack(this.size, buttonCount);\n }\n\n /**\n * The size of buttons to use for the actions.\n */\n @property({ attribute: 'button-size' })\n buttonSize?: ButtonSize;\n\n /**\n * The size of the action set. Different button arrangements are used at\n * different sizes, to make best use of the available space.\n */\n @property()\n size: ButtonSize = 'md';\n\n /**\n * When true, prevents automatic stacking of buttons even when size would\n * normally trigger stacking (e.g., 'sm' size or 'md' with 3+ actions).\n * Buttons will remain in a horizontal layout.\n */\n @property({ type: Boolean, attribute: 'disable-stacking' })\n disableStacking: boolean = false;\n\n /**\n * Array of action button configurations. When provided, buttons will be\n * rendered internally instead of using slotted content.\n */\n @property({ type: Array })\n actions: ActionButton[] = [];\n\n static styles = styles;\n\n /**\n * Applies common button styling (size, classes, expressive attribute)\n * @private\n */\n private _applyButtonStyles(button: HTMLElement, kind?: ButtonKind) {\n if (this.buttonSize) {\n button.setAttribute('size', this.buttonSize);\n }\n\n button.classList.add(`${blockClass}__action-button`);\n\n if (kind === 'ghost' || kind === 'danger--ghost') {\n button.classList.add(`${blockClass}__action-button--ghost`);\n }\n\n button.setAttribute('is-expressive', 'true');\n }\n\n /**\n * Processes actions: validates, determines stacking, and sorts\n * @private\n */\n private _processActions(actions: ActionButton[]): {\n sortedActions: ActionButton[];\n stacking: boolean;\n problems: string[];\n } {\n const problems = validateActionSet(actions, this.size);\n const stacking = this.disableStacking\n ? false\n : willStack(this.size, actions.length);\n const sortedActions = sortActions(actions, stacking);\n\n if (problems.length > 0) {\n pconsole.warn(\n `Invalid actions in ActionSet: ${problems.join(', and ')}.`\n );\n }\n\n return { sortedActions, stacking, problems };\n }\n\n /**\n * Handler for @slotchange, processes and orders buttons based on ActionSet logic\n *\n * @private\n */\n protected _handleSlotChange(event: Event) {\n const childItems = (event.target as HTMLSlotElement)\n .assignedNodes()\n .filter((elem) =>\n (elem as HTMLElement).matches !== undefined\n ? (elem as HTMLElement).matches(`${carbonPrefix}-button`)\n : false\n ) as HTMLElement[];\n\n if (childItems.length === 0) {\n return;\n }\n\n // Extract button properties to create ActionButton objects\n const actions: ActionButton[] = childItems.map((button) => {\n const kind = button.getAttribute('kind') as ButtonKind;\n const disabled = button.hasAttribute('disabled');\n const label = button.textContent?.trim() || '';\n\n return {\n kind: kind || 'primary',\n disabled,\n label,\n };\n });\n\n // Process actions (validate, sort, determine stacking)\n const { sortedActions } = this._processActions(actions);\n\n // Update state\n this._slottedButtonCount = childItems.length;\n\n // Reorder and style the buttons\n this._reorderButtons(childItems, sortedActions);\n\n // Dispatch update event\n const update = new CustomEvent(`${prefix}-action-set-update`, {\n bubbles: true,\n cancelable: true,\n composed: true,\n });\n\n this.dispatchEvent(update);\n }\n\n /**\n * Reorders the button elements in the DOM based on the sorted actions\n * and applies appropriate styling\n *\n * @private\n */\n private _reorderButtons(\n buttons: HTMLElement[],\n sortedActions: ActionButton[]\n ) {\n // Create a map of button labels to elements for quick lookup\n const buttonMap = new Map<string, HTMLElement>();\n buttons.forEach((button) => {\n const label = button.textContent?.trim() || '';\n buttonMap.set(label, button);\n });\n // Apply styling to buttons based on sorted order\n sortedActions.forEach((action) => {\n const button = buttonMap.get(action.label || '');\n if (button) {\n this._applyButtonStyles(button, action.kind);\n }\n });\n }\n\n /**\n * When a button within the action-set is focused, hide the margin on both sides\n * of the focused button, by applying the appropriate styles to its sibling\n *\n * @private\n */\n private _hideSiblingMargin = () => {\n let items: HTMLElement[] = [];\n\n // Check if we have slotted content\n const slot = this.shadowRoot?.querySelector('slot');\n if (slot) {\n items = slot\n .assignedElements()\n .filter(\n (el) => el.tagName.toLowerCase() === `${carbonPrefix}-button`\n ) as HTMLElement[];\n }\n\n // If no slotted content, check for directly rendered buttons in shadow DOM\n if (items.length === 0 && this.shadowRoot) {\n items = Array.from(\n this.shadowRoot.querySelectorAll(`${carbonPrefix}-button`)\n ) as HTMLElement[];\n }\n\n if (items.length === 0) {\n return;\n }\n\n const focusedIndex = items.findIndex((el) => el.matches(':focus-within'));\n\n items.forEach((el, idx) => {\n const shouldHide =\n focusedIndex >= 0 && (idx === focusedIndex || idx === focusedIndex + 1);\n el.toggleAttribute('hide-margin', shouldHide);\n });\n };\n\n connectedCallback() {\n super.connectedCallback();\n this.addEventListener('focusin', this._hideSiblingMargin);\n this.addEventListener('focusout', this._hideSiblingMargin);\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n this.removeEventListener('focusin', this._hideSiblingMargin);\n this.removeEventListener('focusout', this._hideSiblingMargin);\n }\n\n /**\n * Renders buttons from the actions prop\n * @private\n */\n private _renderActionsFromProp() {\n if (!this.actions || this.actions.length === 0) {\n return null;\n }\n\n // Process actions (validate, sort)\n const { sortedActions } = this._processActions(this.actions);\n\n return sortedActions.map((action) => {\n const {\n kind = 'primary',\n label = '',\n disabled = false,\n loading = false,\n onClick,\n class: customClass,\n ...rest\n } = action;\n\n // Merge custom class with action-set classes\n const buttonClasses = classMap({\n [`${blockClass}__action-button`]: true,\n [`${blockClass}__action-button--ghost`]:\n kind === 'ghost' || kind === 'danger--ghost',\n ...(customClass ? { [customClass]: true } : {}),\n });\n\n // Create a ref callback to apply rest properties (excluding class which is handled above)\n const buttonRef = (el: Element | undefined) => {\n if (el && rest) {\n Object.entries(rest).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n if (typeof value === 'boolean') {\n if (value) {\n el.setAttribute(key, '');\n } else {\n el.removeAttribute(key);\n }\n } else {\n el.setAttribute(key, String(value));\n }\n }\n });\n }\n };\n\n return html`\n <cds-button\n ${ref(buttonRef)}\n class=\"${buttonClasses}\"\n kind=\"${kind}\"\n size=\"${this.buttonSize}\"\n ?disabled=\"${disabled || loading}\"\n is-expressive=\"true\"\n @click=\"${typeof onClick === 'function' ? onClick : () => {}}\"\n >\n ${label}\n </cds-button>\n `;\n });\n }\n\n render() {\n const { actions, _slottedButtonCount, stacked } = this;\n const buttonCount = actions?.length || _slottedButtonCount;\n\n const defaultClasses = {\n [blockClass]: true,\n [`${blockClass}--row-single`]: !stacked && buttonCount === 1,\n [`${blockClass}--row-double`]: !stacked && buttonCount === 2,\n [`${blockClass}--row-triple`]: !stacked && buttonCount === 3,\n [`${blockClass}--row-quadruple`]: !stacked && buttonCount >= 4,\n [`${blockClass}--stacking`]: stacked,\n [`${blockClass}--${this.size}`]: true,\n };\n\n // If actions prop is provided, render buttons directly without cds-button-set\n // to avoid button-set's automatic kind assignment\n if (actions && actions.length > 0) {\n const buttonSetClasses = classMap({\n ...defaultClasses,\n [`${carbonPrefix}--btn-set--stacked`]: stacked,\n [`${carbonPrefix}--btn-set`]: true,\n });\n\n return html`<div\n class=\"${buttonSetClasses}\"\n part=\"action-set\"\n role=\"list\"\n >\n ${this._renderActionsFromProp()}\n </div>`;\n }\n\n const classes = classMap({\n ...defaultClasses,\n [`${carbonPrefix}--btn-set--stacked`]: stacked,\n [`${carbonPrefix}--btn-set`]: true,\n });\n return html`<div class=\"${classes}\" part=\"action-set\" role=\"list\">\n <slot @slotchange=\"${this._handleSlotChange}\"></slot>\n </div>`;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'c4p-action-set': CDSActionSet;\n }\n}\n\nexport default CDSActionSet;\n"],"mappings":"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"}
|