UNPKG

@carbon/ibm-products-web-components

Version:
169 lines (166 loc) 6.26 kB
/** * Copyright IBM Corp. 2020, 2026 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ import "../../../globals/settings.js"; import { __decorate } from "../../../_virtual/_@oxc-project_runtime@0.127.0/helpers/decorate.js"; import page_header_actions_set_default$1 from "./page-header-actions-set.scss.js"; import { LitElement, html } from "lit"; import { property, query, state } from "lit/decorators.js"; import { carbonElement } from "@carbon/web-components/es/globals/decorators/carbon-element.js"; import { iconLoader } from "@carbon/web-components/es/globals/internal/icon-loader.js"; import { repeat } from "lit/directives/repeat.js"; import '@carbon/web-components/es-custom/components/overflow-menu/index.js'; import OverflowMenuVertical16 from "@carbon/icons/es/overflow-menu--vertical/16.js"; //#region src/components/page-header/page-header-actions-set/page-header-actions-set.ts /** * @license * * Copyright IBM Corp. 2025, 2026 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ const blockClass = `c4p--page-header-actions-set`; let CDSPageHeaderActionsSet = class CDSPageHeaderActionsSet extends LitElement { constructor(..._args) { super(..._args); this.hiddenItems = []; this.actionsData = []; this.overflowAriaLabel = "More page actions"; this.isSetup = false; this.lastContainerWidth = 0; } connectedCallback() { super.connectedCallback(); this.style.visibility = "hidden"; } firstUpdated() { if (!this.container) return; this.updateComplete.then(() => { requestAnimationFrame(() => { this.setupOverflowDetection(); this.isSetup = true; this.style.visibility = "visible"; }); }); } updated(changedProperties) { if (this.isSetup && changedProperties.has("actionsData") && !changedProperties.has("hiddenItems")) this.updateComplete.then(() => { requestAnimationFrame(() => this.setupOverflowDetection()); }); } setupOverflowDetection() { if (!this.itemsContainer) return; this.resizeObserver?.disconnect(); const slot = this.shadowRoot?.querySelector("slot"); const checkOverflow = () => { const slottedElements = slot?.assignedElements(); if (!slottedElements || slottedElements.length === 0) return; const containerWidth = this.offsetWidth || this.itemsContainer.clientWidth; const overflowMenuWidth = 48; if (containerWidth === 0) return; if (Math.abs(containerWidth - this.lastContainerWidth) < 5) return; this.lastContainerWidth = containerWidth; let totalWidth = 0; for (let i = 0; i < slottedElements.length; i++) totalWidth += slottedElements[i].offsetWidth; if (totalWidth <= containerWidth) { slottedElements.forEach((el) => { el.removeAttribute("data-hidden"); }); this.hiddenItems = []; return; } totalWidth = 0; let visibleCount = 0; for (let i = 0; i < slottedElements.length; i++) { const itemWidth = slottedElements[i].offsetWidth; if (totalWidth + itemWidth + overflowMenuWidth <= containerWidth) { totalWidth += itemWidth; visibleCount = i + 1; } else break; } slottedElements.forEach((el, index) => { if (index >= visibleCount) el.setAttribute("data-hidden", ""); else el.removeAttribute("data-hidden"); }); this.hiddenItems = this.actionsData?.slice(visibleCount) || []; }; checkOverflow(); this.resizeObserver = new ResizeObserver(() => { if (this.resizeTimeout) clearTimeout(this.resizeTimeout); this.resizeTimeout = window.setTimeout(() => { checkOverflow(); }, 100); }); this.resizeObserver.observe(this); this.resizeObserver.observe(this.itemsContainer); } disconnectedCallback() { super.disconnectedCallback(); this.resizeObserver?.disconnect(); if (this.resizeTimeout) clearTimeout(this.resizeTimeout); } handleOverflowItemClick(index) { const button = ((this.shadowRoot?.querySelector("slot"))?.assignedElements())[this.actionsData.length - this.hiddenItems.length + index]; if (button) button.click(); } render() { return html` <ul class="${blockClass}"> <li class="${blockClass}__items"> <slot></slot> </li> <li data-offset ?data-hidden=${this.hiddenItems.length === 0}> <cds-custom-overflow-menu size="md" close-on-activation enter-delay-ms="0" leave-delay-ms="0" align="left" data-floating-menu-container aria-label="${this.overflowAriaLabel}" > ${iconLoader(OverflowMenuVertical16, { class: `${blockClass}__overflow-svg`, slot: "icon" })} <span slot="tooltip-content">More actions</span> <cds-custom-overflow-menu-body flipped> ${repeat(this.hiddenItems ?? [], (_item, index) => index, (item, index) => html` <cds-custom-overflow-menu-item @click="${() => this.handleOverflowItemClick(index)}" > ${item.label} </cds-custom-overflow-menu-item> `)} </cds-custom-overflow-menu-body> </cds-custom-overflow-menu> </li> </ul> `; } static { this.styles = page_header_actions_set_default$1; } }; __decorate([state()], CDSPageHeaderActionsSet.prototype, "hiddenItems", void 0); __decorate([property({ type: Array, attribute: "actions-data", reflect: true })], CDSPageHeaderActionsSet.prototype, "actionsData", void 0); __decorate([property({ type: String, attribute: "overflow-aria-label", reflect: true })], CDSPageHeaderActionsSet.prototype, "overflowAriaLabel", void 0); __decorate([query(`.${blockClass}`)], CDSPageHeaderActionsSet.prototype, "container", void 0); __decorate([query(`.${blockClass}__items`)], CDSPageHeaderActionsSet.prototype, "itemsContainer", void 0); CDSPageHeaderActionsSet = __decorate([carbonElement(`c4p-page-header-actions-set`)], CDSPageHeaderActionsSet); var page_header_actions_set_default = CDSPageHeaderActionsSet; //#endregion export { page_header_actions_set_default as default }; //# sourceMappingURL=page-header-actions-set.js.map