diff --git a/packages/base/src/UI5Element.ts b/packages/base/src/UI5Element.ts index 2d99b3597fcb..40521613c78d 100644 --- a/packages/base/src/UI5Element.ts +++ b/packages/base/src/UI5Element.ts @@ -44,6 +44,7 @@ import type I18nBundle from "./i18nBundle.js"; import { fetchCldr } from "./asset-registries/LocaleData.js"; import getLocale from "./locale/getLocale.js"; import { getLanguageChangePending } from "./config/Language.js"; +import createInstanceChecker from "./util/createInstanceChecker.js"; const DEV_MODE = true; let autoId = 0; @@ -1412,9 +1413,7 @@ abstract class UI5Element extends HTMLElement { /** * Always use duck-typing to cover all runtimes on the page. */ -const instanceOfUI5Element = (object: any): object is UI5Element => { - return "isUI5Element" in object; -}; +const instanceOfUI5Element = createInstanceChecker("isUI5Element"); export default UI5Element; export { diff --git a/packages/base/src/util/createInstanceChecker.ts b/packages/base/src/util/createInstanceChecker.ts new file mode 100644 index 000000000000..9a0b52fe67de --- /dev/null +++ b/packages/base/src/util/createInstanceChecker.ts @@ -0,0 +1,7 @@ +function createChecker(prop: P) { + return (object: any): object is T => { + return object !== undefined && prop in object && object[prop] === true; + }; +} + +export default createChecker; diff --git a/packages/fiori/src/SideNavigationGroup.ts b/packages/fiori/src/SideNavigationGroup.ts index fc52a859e511..22e380dec52e 100644 --- a/packages/fiori/src/SideNavigationGroup.ts +++ b/packages/fiori/src/SideNavigationGroup.ts @@ -23,6 +23,7 @@ import { // Styles import SideNavigationGroupCss from "./generated/themes/SideNavigationGroup.css.js"; +import createInstanceChecker from "@ui5/webcomponents-base/dist/util/createInstanceChecker.js"; /** * @class @@ -196,9 +197,5 @@ class SideNavigationGroup extends SideNavigationItemBase { SideNavigationGroup.define(); -const isInstanceOfSideNavigationGroup = (object: any): object is SideNavigationGroup => { - return "isSideNavigationGroup" in object; -}; - +export const isInstanceOfSideNavigationGroup = createInstanceChecker("isSideNavigationGroup"); export default SideNavigationGroup; -export { isInstanceOfSideNavigationGroup }; diff --git a/packages/fiori/src/SideNavigationItem.ts b/packages/fiori/src/SideNavigationItem.ts index ac1237316d19..2f78bd5c0361 100644 --- a/packages/fiori/src/SideNavigationItem.ts +++ b/packages/fiori/src/SideNavigationItem.ts @@ -26,6 +26,7 @@ import SideNavigationItemTemplate from "./SideNavigationItemTemplate.js"; // Styles import SideNavigationItemCss from "./generated/themes/SideNavigationItem.css.js"; +import createInstanceChecker from "@ui5/webcomponents-base/dist/util/createInstanceChecker.js"; /** * @class @@ -337,9 +338,5 @@ class SideNavigationItem extends SideNavigationSelectableItemBase { SideNavigationItem.define(); -const isInstanceOfSideNavigationItem = (object: any): object is SideNavigationItem => { - return "isSideNavigationItem" in object; -}; - export default SideNavigationItem; -export { isInstanceOfSideNavigationItem }; +export const isInstanceOfSideNavigationItem = createInstanceChecker("isSideNavigationItem"); diff --git a/packages/fiori/src/SideNavigationItemBase.ts b/packages/fiori/src/SideNavigationItemBase.ts index c0c925e2c533..7b5f8296d9fe 100644 --- a/packages/fiori/src/SideNavigationItemBase.ts +++ b/packages/fiori/src/SideNavigationItemBase.ts @@ -5,6 +5,7 @@ import { } from "@ui5/webcomponents-base/dist/Device.js"; import type { ITabbable } from "@ui5/webcomponents-base/dist/delegate/ItemNavigation.js"; import type SideNavigation from "./SideNavigation.js"; +import createInstanceChecker from "@ui5/webcomponents-base/dist/util/createInstanceChecker.js"; type SideNavigationItemClickEventDetail = { altKey: boolean; @@ -154,12 +155,8 @@ class SideNavigationItemBase extends UI5Element implements ITabbable { } } -const isInstanceOfSideNavigationItemBase = (object: any): object is SideNavigationItemBase => { - return "isSideNavigationItemBase" in object; -}; - export default SideNavigationItemBase; export type { SideNavigationItemClickEventDetail, }; -export { isInstanceOfSideNavigationItemBase }; +export const isInstanceOfSideNavigationItemBase = createInstanceChecker("isSideNavigationItemBase"); diff --git a/packages/fiori/src/SideNavigationSelectableItemBase.ts b/packages/fiori/src/SideNavigationSelectableItemBase.ts index a7336fd98761..c77ccbdb8aa0 100644 --- a/packages/fiori/src/SideNavigationSelectableItemBase.ts +++ b/packages/fiori/src/SideNavigationSelectableItemBase.ts @@ -14,6 +14,7 @@ import SideNavigationItemBase from "./SideNavigationItemBase.js"; import type SideNavigationItemDesign from "./types/SideNavigationItemDesign.js"; import type { AccessibilityAttributes } from "@ui5/webcomponents-base/dist/types.js"; import type { SideNavigationItemClickEventDetail } from "./SideNavigationItemBase.js"; +import createInstanceChecker from "@ui5/webcomponents-base/dist/util/createInstanceChecker.js"; type SideNavigationItemAccessibilityAttributes = Pick; @@ -334,14 +335,8 @@ class SideNavigationSelectableItemBase extends SideNavigationItemBase { } } -const isInstanceOfSideNavigationSelectableItemBase = (object: any): object is SideNavigationSelectableItemBase => { - return "isSideNavigationSelectableItemBase" in object; -}; - export default SideNavigationSelectableItemBase; -export { - isInstanceOfSideNavigationSelectableItemBase, -}; +export const isInstanceOfSideNavigationSelectableItemBase = createInstanceChecker("isSideNavigationSelectableItemBase"); export type { SideNavigationItemAccessibilityAttributes, }; diff --git a/packages/fiori/src/UserMenuItemGroup.ts b/packages/fiori/src/UserMenuItemGroup.ts index f76deb857028..fa9052674fe7 100644 --- a/packages/fiori/src/UserMenuItemGroup.ts +++ b/packages/fiori/src/UserMenuItemGroup.ts @@ -1,6 +1,7 @@ import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js"; import MenuItemGroup from "@ui5/webcomponents/dist/MenuItemGroup.js"; import UserMenuItemGroupTemplate from "./UserMenuItemGroupTemplate.js"; +import createInstanceChecker from "@ui5/webcomponents-base/dist/util/createInstanceChecker.js"; /** * @class @@ -39,14 +40,8 @@ import UserMenuItemGroupTemplate from "./UserMenuItemGroupTemplate.js"; class UserMenuItemGroup extends MenuItemGroup { } -const isInstanceOfUserMenuItemGroup = (object: any): object is UserMenuItemGroup => { - return "isGroup" in object; -}; - UserMenuItemGroup.define(); export default UserMenuItemGroup; -export { - isInstanceOfUserMenuItemGroup, -}; +export const isInstanceOfUserMenuItemGroup = createInstanceChecker("isGroup"); diff --git a/packages/main/src/ComboBoxItemGroup.ts b/packages/main/src/ComboBoxItemGroup.ts index e26342dd0b54..9ba838c72a84 100644 --- a/packages/main/src/ComboBoxItemGroup.ts +++ b/packages/main/src/ComboBoxItemGroup.ts @@ -4,6 +4,7 @@ import type { IComboBoxItem } from "./ComboBox.js"; import ListItemGroup from "./ListItemGroup.js"; import type ComboBoxItem from "./ComboBoxItem.js"; import ComboBoxItemGroupTemplate from "./ComboBoxItemGroupTemplate.js"; +import createInstanceChecker from "@ui5/webcomponents-base/dist/util/createInstanceChecker.js"; /** * @class @@ -45,9 +46,5 @@ class ComboBoxItemGroup extends ListItemGroup implements IComboBoxItem { ComboBoxItemGroup.define(); -const isInstanceOfComboBoxItemGroup = (object: any): object is ComboBoxItemGroup => { - return "isGroupItem" in object; -}; - -export { isInstanceOfComboBoxItemGroup }; +export const isInstanceOfComboBoxItemGroup = createInstanceChecker("isGroupItem"); export default ComboBoxItemGroup; diff --git a/packages/main/src/ListItemGroup.ts b/packages/main/src/ListItemGroup.ts index 71d649c2edc4..dcc803b6b926 100644 --- a/packages/main/src/ListItemGroup.ts +++ b/packages/main/src/ListItemGroup.ts @@ -16,6 +16,7 @@ import ListItemGroupTemplate from "./ListItemGroupTemplate.js"; import ListItemGroupCss from "./generated/themes/ListItemGroup.css.js"; import type ListItemGroupHeader from "./ListItemGroupHeader.js"; import WrappingType from "./types/WrappingType.js"; +import createInstanceChecker from "@ui5/webcomponents-base/dist/util/createInstanceChecker.js"; type ListItemGroupMoveEventDetail = { source: { @@ -213,10 +214,6 @@ class ListItemGroup extends UI5Element { ListItemGroup.define(); -const isInstanceOfListItemGroup = (object: any): object is ListItemGroup => { - return "isListItemGroup" in object; -}; - export default ListItemGroup; -export { isInstanceOfListItemGroup }; +export const isInstanceOfListItemGroup = createInstanceChecker("isListItemGroup"); export type { ListItemGroupMoveEventDetail }; diff --git a/packages/main/src/MenuItem.ts b/packages/main/src/MenuItem.ts index f9db130beec8..0b9eefd064e9 100644 --- a/packages/main/src/MenuItem.ts +++ b/packages/main/src/MenuItem.ts @@ -42,6 +42,7 @@ import type { IMenuItem } from "./Menu.js"; // Styles import menuItemCss from "./generated/themes/MenuItem.css.js"; +import createInstanceChecker from "@ui5/webcomponents-base/dist/util/createInstanceChecker.js"; type MenuBeforeOpenEventDetail = { item?: MenuItem }; type MenuBeforeCloseEventDetail = { escPressed: boolean }; @@ -663,10 +664,6 @@ class MenuItem extends ListItem implements IMenuItem { MenuItem.define(); -const isInstanceOfMenuItem = (object: any): object is MenuItem => { - return "isMenuItem" in object; -}; - export default MenuItem; export type { @@ -675,6 +672,4 @@ export type { MenuItemAccessibilityAttributes, }; -export { - isInstanceOfMenuItem, -}; +export const isInstanceOfMenuItem = createInstanceChecker("isMenuItem"); diff --git a/packages/main/src/MenuItemGroup.ts b/packages/main/src/MenuItemGroup.ts index ae9fc3445640..af5ef1b74429 100644 --- a/packages/main/src/MenuItemGroup.ts +++ b/packages/main/src/MenuItemGroup.ts @@ -15,6 +15,7 @@ import { MENU_ITEM_GROUP_SINGLE_ACCESSIBLE_NAME, MENU_ITEM_GROUP_MULTI_ACCESSIBLE_NAME, } from "./generated/i18n/i18n-defaults.js"; +import createInstanceChecker from "@ui5/webcomponents-base/dist/util/createInstanceChecker.js"; /** * @class @@ -148,14 +149,8 @@ class MenuItemGroup extends UI5Element implements IMenuItem { } } -const isInstanceOfMenuItemGroup = (object: any): object is MenuItemGroup => { - return "isGroup" in object; -}; - MenuItemGroup.define(); export default MenuItemGroup; -export { - isInstanceOfMenuItemGroup, -}; +export const isInstanceOfMenuItemGroup = createInstanceChecker("isGroup"); diff --git a/packages/main/src/MenuSeparator.ts b/packages/main/src/MenuSeparator.ts index 43b5a74536d3..4905287f6b1b 100644 --- a/packages/main/src/MenuSeparator.ts +++ b/packages/main/src/MenuSeparator.ts @@ -5,6 +5,7 @@ import menuSeparatorTemplate from "./MenuSeparatorTemplate.js"; import menuSeparatorCss from "./generated/themes/MenuSeparator.css.js"; import ListItemBase from "./ListItemBase.js"; import type { IMenuItem } from "./Menu.js"; +import createInstanceChecker from "@ui5/webcomponents-base/dist/util/createInstanceChecker.js"; /** * @class * The `ui5-menu-separator` represents a horizontal line to separate menu items inside a `ui5-menu`. @@ -51,14 +52,8 @@ class MenuSeparator extends ListItemBase implements IMenuItem { } } -const isInstanceOfMenuSeparator = (object: any): object is MenuSeparator => { - return "isSeparator" in object; -}; - MenuSeparator.define(); export default MenuSeparator; -export { - isInstanceOfMenuSeparator, -}; +export const isInstanceOfMenuSeparator = createInstanceChecker("isSeparator"); diff --git a/packages/main/src/MultiComboBoxItem.ts b/packages/main/src/MultiComboBoxItem.ts index ba9bf46a33f1..2f671bc48acf 100644 --- a/packages/main/src/MultiComboBoxItem.ts +++ b/packages/main/src/MultiComboBoxItem.ts @@ -16,6 +16,7 @@ import styles from "./generated/themes/MultiComboBoxItem.css.js"; import MultiComboBoxItemTemplate from "./MultiComboBoxItemTemplate.js"; import type { SelectionRequestEventDetail } from "./ListItem.js"; import type { AriaRole } from "@ui5/webcomponents-base"; +import createInstanceChecker from "@ui5/webcomponents-base/dist/util/createInstanceChecker.js"; /** * @class @@ -83,11 +84,7 @@ class MultiComboBoxItem extends ComboBoxItem implements IMultiComboBoxItem { } } -const isInstanceOfMultiComboBoxItem = (object: any): object is MultiComboBoxItem => { - return "isMultiComboBoxItem" in object; -}; - MultiComboBoxItem.define(); export default MultiComboBoxItem; -export { isInstanceOfMultiComboBoxItem }; +export const isInstanceOfMultiComboBoxItem = createInstanceChecker("isMultiComboBoxItem"); diff --git a/packages/main/src/MultiComboBoxItemGroup.ts b/packages/main/src/MultiComboBoxItemGroup.ts index 1ead17421993..6b373d4efde0 100644 --- a/packages/main/src/MultiComboBoxItemGroup.ts +++ b/packages/main/src/MultiComboBoxItemGroup.ts @@ -5,6 +5,7 @@ import type MultiComboBoxItem from "./MultiComboBoxItem.js"; import MultiComboBoxItemGroupTemplate from "./MultiComboBoxItemGroupTemplate.js"; import type ListItemGroupHeader from "./ListItemGroupHeader.js"; import ComboBoxItemGroup from "./ComboBoxItemGroup.js"; +import createInstanceChecker from "@ui5/webcomponents-base/dist/util/createInstanceChecker.js"; /** * @class @@ -57,10 +58,6 @@ class MultiComboBoxItemGroup extends ComboBoxItemGroup implements IMultiComboBox MultiComboBoxItemGroup.define(); -const isInstanceOfMultiComboBoxItemGroup = (object: any): object is MultiComboBoxItemGroup => { - return "isGroupItem" in object; -}; - export default MultiComboBoxItemGroup; -export { isInstanceOfMultiComboBoxItemGroup }; +export const isInstanceOfMultiComboBoxItemGroup = createInstanceChecker("isGroupItem"); diff --git a/packages/main/src/Popover.ts b/packages/main/src/Popover.ts index a5412410cc91..af9b66243879 100644 --- a/packages/main/src/Popover.ts +++ b/packages/main/src/Popover.ts @@ -21,6 +21,7 @@ import PopoverTemplate from "./PopoverTemplate.js"; // Styles import PopupsCommonCss from "./generated/themes/PopupsCommon.css.js"; import PopoverCss from "./generated/themes/Popover.css.js"; +import createInstanceChecker from "@ui5/webcomponents-base/dist/util/createInstanceChecker.js"; const ARROW_SIZE = 8; @@ -969,14 +970,13 @@ class Popover extends Popup { this._popoverResize.onResizeMouseDown(e); this._resizeHandlePlacement = this._popoverResize.getResizeHandlePlacement(); } -} -const instanceOfPopover = (object: any): object is Popover => { - return "opener" in object; -}; + // for instance checks + readonly isPopover = true; +} Popover.define(); export default Popover; - -export { instanceOfPopover, PopoverActualPlacement, PopoverActualHorizontalAlign }; +export const instanceOfPopover = createInstanceChecker("isPopover"); +export { PopoverActualPlacement, PopoverActualHorizontalAlign }; diff --git a/packages/main/src/TableUtils.ts b/packages/main/src/TableUtils.ts index a6386d39651f..e6204295d0b0 100644 --- a/packages/main/src/TableUtils.ts +++ b/packages/main/src/TableUtils.ts @@ -1,9 +1,8 @@ +import createInstanceChecker from "@ui5/webcomponents-base/dist/util/createInstanceChecker.js"; import type Table from "./Table.js"; import type TableRow from "./TableRow.js"; -const isInstanceOfTable = (obj: any): obj is Table => { - return !!obj && "isTable" in obj && !!obj.isTable; -}; +const isInstanceOfTable = createInstanceChecker("isTable"); const isSelectionCell = (e: Event) => { return e.composedPath().some((el: EventTarget) => (el as HTMLElement).hasAttribute?.("data-ui5-table-selection-cell")); diff --git a/packages/main/src/Tree.ts b/packages/main/src/Tree.ts index d4ece8b3ac05..adc5824aa33e 100644 --- a/packages/main/src/Tree.ts +++ b/packages/main/src/Tree.ts @@ -30,6 +30,7 @@ import TreeTemplate from "./TreeTemplate.js"; // Styles import TreeCss from "./generated/themes/Tree.css.js"; +import createInstanceChecker from "@ui5/webcomponents-base/dist/util/createInstanceChecker.js"; type TreeMoveEventDetail = { source: { @@ -412,7 +413,7 @@ class Tree extends UI5Element { _onListItemMouseOver(e: MouseEvent) { const target = e.target; - if (this._isInstanceOfTreeItemBase(target)) { + if (_isInstanceOfTreeItemBase(target)) { this.fireDecoratorEvent("item-mouseover", { item: target }); } } @@ -420,7 +421,7 @@ class Tree extends UI5Element { _onListItemMouseOut(e: MouseEvent) { const target = e.target; - if (this._isInstanceOfTreeItemBase(target)) { + if (_isInstanceOfTreeItemBase(target)) { this.fireDecoratorEvent("item-mouseout", { item: target }); } } @@ -523,12 +524,10 @@ class Tree extends UI5Element { } return placements; } - - _isInstanceOfTreeItemBase(object: any): object is TreeItemBase { - return "isTreeItem" in object; - } } +const _isInstanceOfTreeItemBase = createInstanceChecker("isTreeItem"); + const walkTree = (el: Tree | TreeItemBase, level: number, callback: WalkCallback) => { (el.items).forEach((item, index) => { callback(item, level, index);