Skip to content

Commit

Permalink
fix(ui5-tabcontainer): replace default slot union type with interface (
Browse files Browse the repository at this point in the history
…#8734)

Related to: #8698
  • Loading branch information
dimovpetar committed Apr 12, 2024
1 parent be67a54 commit ac6b44f
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 24 deletions.
8 changes: 4 additions & 4 deletions packages/main/src/Tab.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ import "@ui5/webcomponents-icons/dist/sys-enter-2.js";
import SemanticColor from "./types/SemanticColor.js";
import ListItemType from "./types/ListItemType.js";
import TabContainer from "./TabContainer.js";
import type TabSeparator from "./TabSeparator.js";
import type { TabContainerStripInfo, TabContainerOverflowInfo } from "./TabContainer.js";
import type { TabContainerStripInfo, TabContainerOverflowInfo, ITab } from "./TabContainer.js";
import Icon from "./Icon.js";
import Button from "./Button.js";
import CustomListItem from "./CustomListItem.js";
Expand Down Expand Up @@ -64,6 +63,7 @@ interface TabInOverflow extends CustomListItem {
* @abstract
* @constructor
* @extends UI5Element
* @implements {ITab}
* @public
*/
@customElement({
Expand All @@ -78,7 +78,7 @@ interface TabInOverflow extends CustomListItem {
CustomListItem,
],
})
class Tab extends UI5Element implements ITabbable {
class Tab extends UI5Element implements ITabbable, ITab {
/**
* The text to be displayed for the item.
* @default ""
Expand Down Expand Up @@ -185,7 +185,7 @@ class Tab extends UI5Element implements ITabbable {
slots: false,
},
})
items!: Array<Tab | TabSeparator>
items!: Array<ITab>

_isInline?: boolean;
_forcedMixedMode?: boolean;
Expand Down
50 changes: 32 additions & 18 deletions packages/main/src/TabContainer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ import List from "./List.js";
import DropIndicator from "./DropIndicator.js";
import type Tab from "./Tab.js";
import type { TabInStrip, TabInOverflow } from "./Tab.js";
import type TabSeparator from "./TabSeparator.js";
import type { TabSeparatorInStrip } from "./TabSeparator.js";
import type { ListItemClickEventDetail, ListMoveEventDetail } from "./List.js";
import ResponsivePopover from "./ResponsivePopover.js";
Expand Down Expand Up @@ -100,6 +99,20 @@ type TabContainerMoveEventDetail = {
}
}

/**
* Interface for components that may be slotted inside `ui5-tabcontainer` as items
*
* **Note:** Use directly `ui5-tab` or `ui5-tab-seprator`. Implementing the interface does not guarantee that the class can work as a tab.
* @public
*/
interface ITab extends UI5Element {
isSeparator: boolean;
receiveStripInfo: (arg0: TabContainerStripInfo) => void;
receiveOverflowInfo: (arg0: TabContainerOverflowInfo) => void;
getDomRefInStrip: () => HTMLElement | undefined;
items?: Array<ITab>;
}

/**
* @class
*
Expand Down Expand Up @@ -312,7 +325,7 @@ class TabContainer extends UI5Element {
_endOverflowText!: string;

@property({ type: Object, multiple: true })
_popoverItemsFlat!: Array<Tab | TabSeparator>;
_popoverItemsFlat!: Array<ITab>;

@property({ validator: Integer, noAttribute: true })
_width?: number;
Expand All @@ -332,7 +345,7 @@ class TabContainer extends UI5Element {
slots: true,
},
})
items!: Array<Tab | TabSeparator>;
items!: Array<ITab>;

/**
* Defines the button which will open the overflow menu. If nothing is provided to this slot,
Expand All @@ -353,7 +366,7 @@ class TabContainer extends UI5Element {
startOverflowButton!: Array<IButton>;

_itemNavigation: ItemNavigation;
_itemsFlat?: Array<Tab | TabSeparator>;
_itemsFlat?: Array<ITab>;
responsivePopover?: ResponsivePopover;
_hasScheduledPopoverOpen = false;
_handleResizeBound: () => void;
Expand Down Expand Up @@ -459,7 +472,7 @@ class TabContainer extends UI5Element {
this.mediaRange = MediaRange.getCurrentRange(MediaRange.RANGESETS.RANGE_4STEPS, width);
}

_sendStripPresentationInfos(items: Array<Tab | TabSeparator>) {
_sendStripPresentationInfos(items: Array<ITab>) {
const setsize = this._getTabs().length;
let posinset = 1;

Expand Down Expand Up @@ -786,12 +799,12 @@ class TabContainer extends UI5Element {
* @public
* @default []
*/
get allItems() : Array<Tab | TabSeparator> {
get allItems() : Array<ITab> {
return this._flatten(this.items);
}

_flatten(items: Array<Tab | TabSeparator>) {
const result: Array<Tab | TabSeparator> = [];
_flatten(items: Array<ITab>) {
const result: Array<ITab> = [];

walk(items, item => {
if (item.hasAttribute("ui5-tab") || item.hasAttribute("ui5-tab-separator")) {
Expand Down Expand Up @@ -869,7 +882,7 @@ class TabContainer extends UI5Element {
await this._togglePopover(opener, true);
}

_setIndentLevels(items: Array<Tab | TabSeparator>, level: number, extraIndent: boolean) {
_setIndentLevels(items: Array<ITab>, level: number, extraIndent: boolean) {
items.forEach(item => {
item.receiveOverflowInfo({
style: {
Expand All @@ -878,13 +891,13 @@ class TabContainer extends UI5Element {
},
});

if (!item.isSeparator) {
this._setIndentLevels((item as Tab).items, level + 1, extraIndent);
if (item.items) {
this._setIndentLevels(item.items, level + 1, extraIndent);
}
});
}

_sendOverflowPresentationInfos(items: Array<Tab | TabSeparator>) {
_sendOverflowPresentationInfos(items: Array<ITab>) {
const extraIndent = items
.filter((item): item is Tab => !item.isSeparator)
.some(tab => tab.design !== SemanticColor.Default && tab.design !== SemanticColor.Neutral);
Expand Down Expand Up @@ -1254,7 +1267,7 @@ class TabContainer extends UI5Element {
return targetOwner.realTabReference.items;
}

_setPopoverItems(items: Array<Tab | TabSeparator>) {
_setPopoverItems(items: Array<ITab>) {
this._sendOverflowPresentationInfos(items);
const newItemsFlat = this._flatten(items);

Expand Down Expand Up @@ -1430,11 +1443,11 @@ const getTabInStrip = (el: HTMLElement | null) => {
return false;
};

const walk = (items: Array<Tab | TabSeparator>, callback: (_: Tab | TabSeparator) => void) => {
[...items].forEach(tab => {
callback(tab);
if (tab.hasAttribute("ui5-tab")) {
walk((tab as Tab).items, callback);
const walk = (items: Array<ITab>, callback: (_: ITab) => void) => {
[...items].forEach(item => {
callback(item);
if (item.hasAttribute("ui5-tab") && item.items) {
walk(item.items, callback);
}
});
};
Expand All @@ -1447,4 +1460,5 @@ export type {
TabContainerMoveEventDetail,
TabContainerStripInfo,
TabContainerOverflowInfo,
ITab,
};
5 changes: 3 additions & 2 deletions packages/main/src/TabSeparator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js";
import executeTemplate from "@ui5/webcomponents-base/dist/renderer/executeTemplate.js";
import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js";
import TabContainer from "./TabContainer.js";
import type { TabContainerStripInfo, TabContainerOverflowInfo } from "./TabContainer.js";
import type { TabContainerStripInfo, TabContainerOverflowInfo, ITab } from "./TabContainer.js";

// Templates
import TabSeparatorInStripTemplate from "./generated/templates/TabSeparatorInStripTemplate.lit.js";
Expand All @@ -22,14 +22,15 @@ interface TabSeparatorInStrip extends HTMLElement {
* The `ui5-tab-separator` represents a vertical line to separate tabs inside a `ui5-tabcontainer`.
* @constructor
* @extends UI5Element
* @implements {ITab}
* @abstract
* @public
*/
@customElement({
tag: "ui5-tab-separator",
renderer: litRender,
})
class TabSeparator extends UI5Element {
class TabSeparator extends UI5Element implements ITab {
_forcedStyleInOverflow?: Record<string, any>;

_getElementInStrip?: () => HTMLElement | undefined;
Expand Down

0 comments on commit ac6b44f

Please sign in to comment.