All Downloads are FREE. Search and download functionalities are using the official Maven repository.

package.dist.Tokenizer.js Maven / Gradle / Ivy

The newest version!
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var Tokenizer_1;
import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js";
import property from "@ui5/webcomponents-base/dist/decorators/property.js";
import slot from "@ui5/webcomponents-base/dist/decorators/slot.js";
import event from "@ui5/webcomponents-base/dist/decorators/event.js";
import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js";
import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js";
import ResizeHandler from "@ui5/webcomponents-base/dist/delegate/ResizeHandler.js";
import { renderFinished } from "@ui5/webcomponents-base/dist/Render.js";
import ItemNavigation from "@ui5/webcomponents-base/dist/delegate/ItemNavigation.js";
import { getEffectiveAriaLabelText } from "@ui5/webcomponents-base/dist/util/AriaLabelHelper.js";
import getActiveElement from "@ui5/webcomponents-base/dist/util/getActiveElement.js";
import { getFocusedElement } from "@ui5/webcomponents-base/dist/util/PopupUtils.js";
import ScrollEnablement from "@ui5/webcomponents-base/dist/delegate/ScrollEnablement.js";
import { getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js";
import DOMReferenceConverter from "@ui5/webcomponents-base/dist/converters/DOMReference.js";
import { isSpace, isSpaceCtrl, isSpaceShift, isLeftCtrl, isRightCtrl, isUpCtrl, isDownCtrl, isUpShift, isDownShift, isLeftShift, isRightShift, isLeftShiftCtrl, isRightShiftCtrl, isDeleteShift, isInsertCtrl, isEnd, isHome, isHomeShift, isEndShift, isPageUpShift, isPageDownShift, isHomeCtrl, isEndCtrl, isRight, isLeft, isUp, isDown, isEscape, } from "@ui5/webcomponents-base/dist/Keys.js";
import { isPhone } from "@ui5/webcomponents-base/dist/Device.js";
import ResponsivePopover from "./ResponsivePopover.js";
import List from "./List.js";
import ListSelectionMode from "./types/ListSelectionMode.js";
import Title from "./Title.js";
import Button from "./Button.js";
import Icon from "./Icon.js";
import ListItemStandard from "./ListItemStandard.js";
import TokenizerTemplate from "./generated/templates/TokenizerTemplate.lit.js";
import { MULTIINPUT_SHOW_MORE_TOKENS, TOKENIZER_ARIA_LABEL, TOKENIZER_POPOVER_REMOVE, TOKENIZER_ARIA_CONTAIN_TOKEN, TOKENIZER_ARIA_CONTAIN_ONE_TOKEN, TOKENIZER_ARIA_CONTAIN_SEVERAL_TOKENS, TOKENIZER_SHOW_ALL_ITEMS, } from "./generated/i18n/i18n-defaults.js";
// Styles
import TokenizerCss from "./generated/themes/Tokenizer.css.js";
import TokenizerPopoverCss from "./generated/themes/TokenizerPopover.css.js";
import ResponsivePopoverCommonCss from "./generated/themes/ResponsivePopoverCommon.css.js";
// reuse suggestions focus styling for NMore popup
import SuggestionsCss from "./generated/themes/Suggestions.css.js";
var ClipboardDataOperation;
(function (ClipboardDataOperation) {
    ClipboardDataOperation["cut"] = "cut";
    ClipboardDataOperation["copy"] = "copy";
})(ClipboardDataOperation || (ClipboardDataOperation = {}));
/**
 * @class
 *
 * ### Overview
 *
 * A `ui5-tokenizer` is an invisible container for `ui5-token`s that supports keyboard navigation and token selection.
 *
 * The `ui5-tokenizer` consists of two parts:
 * - Tokens - displays the available tokens.
 * - N-more indicator - contains the number of the remaining tokens that cannot be displayed due to the limited space.
 *
 * ### Keyboard Handling
 *
 * #### Basic Navigation
 * The `ui5-tokenizer` provides advanced keyboard handling.
 * When a token is focused the user can use the following keyboard
 * shortcuts in order to perform a navigation:
 *
 * - [Left] or [Right] / [Up] or [Down] - Navigates left and right through the tokens.
 * - [Home] - Navigates to the first token.
 * - [End] - Navigates to the last token.
 *
 * The user can use the following keyboard shortcuts to perform actions (such as select, delete):
 *
 * - [Space] - Selects a token.
 * - [Backspace] / [Delete] - Deletes a token.
 * **Note:** The deletion of a token is handled by the application with the use of the `token-delete` event.
 *
 * ### ES6 Module Import
 *
 * `import "@ui5/webcomponents/dist/Tokenizer.js";`
 *
 * @constructor
 * @extends UI5Element
 * @public
 * @since 2.0.0
 * @experimental This component is availabe since 2.0 under an experimental flag and its API and behaviour are subject to change.
 */
let Tokenizer = Tokenizer_1 = class Tokenizer extends UI5Element {
    _handleResize() {
        this._nMoreCount = this.overflownTokens.length;
    }
    constructor() {
        super();
        /**
         * Defines whether the component is read-only.
         *
         * **Note:** A read-only component is not editable,
         * but still provides visual feedback upon user interaction.
         * @default false
         * @public
         */
        this.readonly = false;
        /**
         * Defines whether the component is disabled.
         *
         * **Note:** A disabled component is completely noninteractive.
         * @default false
         * @public
         */
        this.disabled = false;
        /**
         * Indicates if the tokenizer should show all tokens or n more label instead
         * **Note:** Used inside MultiInput and MultiComboBox components.
         * @default false
         * @private
         */
        this.expanded = false;
        /**
         * Indicates if the nMore popover is open
         * **Note:** Used inside MultiInput and MultiComboBox components.
         * @default false
         * @private
         */
        this.open = false;
        /**
         * Prevents tokens to be part of the tab chain.
         * **Note:** Used inside MultiInput and MultiComboBox components.
         * @default false
         * @private
         */
        this.preventInitialFocus = false;
        /**
         * Prevent opening of n-more Popover when label is clicked
         * **Note:** Used inside MultiComboBox component.
         * @default false
         * @private
         */
        this.preventPopoverOpen = false;
        /**
         * Hides the popover arrow.
         * **Note:** Used inside MultiInput and MultiComboBox components.
         * @default false
         * @private
         */
        this.hidePopoverArrow = false;
        this._nMoreCount = 0;
        this._tokensCount = 0;
        this._tokenDeleting = false;
        this._preventCollapse = false;
        this._skipTabIndex = false;
        this._previousToken = null;
        this._resizeHandler = this._handleResize.bind(this);
        this._itemNav = new ItemNavigation(this, {
            currentIndex: -1,
            getItemsCallback: this._getVisibleTokens.bind(this),
        });
        this._scrollEnablement = new ScrollEnablement(this);
        this._deletedDialogItems = [];
    }
    onBeforeRendering() {
        const tokensLength = this._tokens.length;
        this._tokensCount = tokensLength;
        this._tokens.forEach(token => {
            token.singleToken = tokensLength === 1;
            token.readonly = this.readonly;
        });
    }
    onEnterDOM() {
        ResizeHandler.register(this.contentDom, this._resizeHandler);
    }
    onExitDOM() {
        ResizeHandler.deregister(this.contentDom, this._resizeHandler);
    }
    _handleNMoreClick() {
        if (this.disabled) {
            return;
        }
        this.expanded = true;
        if (!this.preventPopoverOpen) {
            this.open = true;
            this.scrollToEnd();
        }
        this._tokens.forEach(token => {
            token.forcedTabIndex = "-1";
        });
        this._skipTabIndex = true;
        this.fireEvent("show-more-items-press");
    }
    _onmousedown(e) {
        if (e.target.hasAttribute("ui5-token")) {
            const target = e.target;
            this.expanded = true;
            if (this.open) {
                this._preventCollapse = true;
            }
            if (!target.toBeDeleted) {
                this._itemNav.setCurrentItem(target);
                this._scrollToToken(target);
            }
        }
    }
    onTokenSelect() {
        const tokens = this._tokens;
        const firstToken = tokens[0];
        if (tokens.length === 1 && firstToken.isTruncatable) {
            this.open = firstToken.selected;
        }
    }
    _getVisibleTokens() {
        if (this.disabled) {
            return [];
        }
        return this._tokens.filter((token, index) => {
            return index < (this._tokens.length - this._nMoreCount);
        });
    }
    onAfterRendering() {
        const tokensArray = this._tokens;
        const firstToken = tokensArray[0];
        this._nMoreCount = this.overflownTokens.length;
        if (firstToken && !this.disabled && !this.preventInitialFocus && !this._skipTabIndex) {
            firstToken.forcedTabIndex = "0";
        }
        this._scrollEnablement.scrollContainer = this.contentDom;
        if (this.expanded) {
            this._expandedScrollWidth = this.contentDom.scrollWidth;
        }
        this._tokenDeleting = false;
    }
    _delete(e) {
        const target = e.target;
        if (!e.detail) { // if there are no details, the event is triggered by a click
            this._tokenClickDelete(e, target);
            this.open = false;
            return;
        }
        this.deleteToken(target, e.detail.backSpace);
    }
    _tokenClickDelete(e, token) {
        const tokens = this._getVisibleTokens();
        const target = e.target;
        const deletedTokenIndex = token ? tokens.indexOf(token) : tokens.indexOf(target); // The index of the token that just got deleted
        const nextTokenIndex = deletedTokenIndex === tokens.length - 1 ? deletedTokenIndex - 1 : deletedTokenIndex + 1; // The index of the next token that needs to be focused next due to the deletion
        const nextToken = tokens[nextTokenIndex]; // if the last item was deleted this will be undefined
        this._handleCurrentItemAfterDeletion(nextToken);
        this._tokenDeleting = true;
        this.fireEvent("token-delete", { tokens: [token] || [target] });
    }
    _handleCurrentItemAfterDeletion(nextToken) {
        if (nextToken && !isPhone()) {
            setTimeout(() => {
                nextToken.focus();
            }, 0);
        }
    }
    /**
     * Removes a token from the Tokenizer.
     * This method should only be used by ui5-multi-combobox and ui5-multi-input
     * @protected
     * @param token Token to be focused.
     * @param forwardFocusToPrevious Indicates whether the focus will be forwarded to previous or next token after deletion.
     */
    deleteToken(token, forwardFocusToPrevious) {
        const tokens = this._getVisibleTokens();
        const deletedTokenIndex = tokens.indexOf(token);
        let nextTokenIndex = (deletedTokenIndex === tokens.length - 1) ? deletedTokenIndex - 1 : deletedTokenIndex + 1;
        const notSelectedTokens = tokens.filter(t => !t.selected);
        if (forwardFocusToPrevious) { // on backspace key select the previous item (unless deleting the first)
            nextTokenIndex = deletedTokenIndex === 0 ? deletedTokenIndex + 1 : deletedTokenIndex - 1;
        }
        else { // on delete key or mouse click on the "x" select the next item (unless deleting the last)
            nextTokenIndex = deletedTokenIndex === tokens.length - 1 ? deletedTokenIndex - 1 : deletedTokenIndex + 1;
        }
        let nextToken = tokens[nextTokenIndex];
        if (notSelectedTokens.length > 1) {
            while (nextToken && nextToken.selected) {
                nextTokenIndex = forwardFocusToPrevious ? --nextTokenIndex : ++nextTokenIndex;
                if (nextTokenIndex < 0) {
                    nextToken = notSelectedTokens[0];
                }
                if (nextTokenIndex > notSelectedTokens.length) {
                    nextToken = notSelectedTokens[notSelectedTokens.length - 1];
                }
            }
        }
        else {
            nextToken = notSelectedTokens[0];
        }
        this._handleCurrentItemAfterDeletion(nextToken);
        this._tokenDeleting = true;
        if (this._selectedTokens.length) {
            this.fireEvent("token-delete", { tokens: this._selectedTokens });
        }
        else {
            this.fireEvent("token-delete", { tokens: [token] });
        }
    }
    async itemDelete(e) {
        const token = e.detail.item.tokenRef;
        const tokensArray = this._tokens;
        // delay the token deletion in order to close the popover before removing token of the DOM
        if (tokensArray.length === 1) {
            const morePopover = this.getPopover();
            morePopover.addEventListener("ui5-close", () => {
                this.fireEvent("token-delete", { tokens: [token] });
            }, {
                once: true,
            });
            this.open = false;
        }
        else {
            if (isPhone()) {
                token._isVisible = false;
                this._deletedDialogItems.push(token);
            }
            else {
                this.fireEvent("token-delete", { tokens: [token] });
            }
            const currentListItem = e.detail.item;
            const nextListItem = currentListItem.nextElementSibling;
            const previousListItem = currentListItem.previousElementSibling;
            const focusItem = nextListItem || previousListItem;
            if (focusItem) {
                await renderFinished();
                focusItem.focus();
            }
        }
    }
    handleBeforeClose() {
        const tokensArray = this._tokens;
        if (isPhone()) {
            tokensArray.forEach(token => {
                token.selected = false;
            });
        }
        if (!this._tokenDeleting && !this._preventCollapse) {
            this._preventCollapse = false;
            this.expanded = false;
        }
    }
    handleBeforeOpen() {
        this._tokens.forEach(token => {
            token._isVisible = true;
        });
        const list = this._getList();
        const firstListItem = list.querySelectorAll("[ui5-li]")[0];
        list._itemNavigation.setCurrentItem(firstListItem);
        this.fireEvent("before-more-popover-open");
    }
    handleAfterClose() {
        this.open = false;
        this._preventCollapse = false;
        this._focusedElementBeforeOpen = null;
        this._tokens.forEach(token => {
            token._isVisible = true;
        });
    }
    handleDialogButtonPress(e) {
        const isOkButton = e.target.hasAttribute("data-ui5-tokenizer-dialog-ok-button");
        const confirm = !!isOkButton;
        if (confirm && this._deletedDialogItems.length) {
            this.fireEvent("token-delete", { tokens: this._deletedDialogItems });
        }
        this.open = false;
    }
    _onkeydown(e) {
        const isCtrl = !!(e.metaKey || e.ctrlKey);
        if ((isCtrl && ["c", "x"].includes(e.key.toLowerCase())) || isDeleteShift(e) || isInsertCtrl(e)) {
            e.preventDefault();
            const isCut = e.key.toLowerCase() === "x" || isDeleteShift(e);
            const selectedTokens = this._tokens.filter(token => token.selected);
            const focusedToken = selectedTokens.find(token => token.focused);
            if (isCut) {
                const cutResult = this._fillClipboard(ClipboardDataOperation.cut, selectedTokens);
                focusedToken && this.deleteToken(focusedToken);
                return cutResult;
            }
            return this._fillClipboard(ClipboardDataOperation.copy, selectedTokens);
        }
        if (isCtrl && e.key.toLowerCase() === "i" && this._tokens.length > 0) {
            e.preventDefault();
            this._preventCollapse = true;
            this._focusedElementBeforeOpen = getFocusedElement();
            this.open = true;
        }
        if (isSpaceShift(e)) {
            e.preventDefault();
        }
        if (isSpace(e) || isSpaceCtrl(e)) {
            e.preventDefault();
            return this._handleTokenSelection(e, false);
        }
        if (isHomeShift(e) || isPageUpShift(e)) {
            this._handleHomeShift(e);
        }
        if (isEndShift(e) || isPageDownShift(e)) {
            this._handleEndShift(e);
        }
        this._handleItemNavigation(e, this._tokens);
    }
    _onPopoverListKeydown(e) {
        const isCtrl = !!(e.metaKey || e.ctrlKey);
        if ((isCtrl && e.key.toLowerCase() === "i") || isEscape(e)) {
            e.preventDefault();
            this.open = false;
            this._preventCollapse = true;
            this._focusedElementBeforeOpen && this._focusedElementBeforeOpen.focus();
            if (!this._focusedElementBeforeOpen) {
                this._focusLastToken();
            }
        }
        if (e.key.toLowerCase() === "f7") {
            e.preventDefault();
            const eventTarget = e.target;
            const activeElement = getActiveElement();
            if (activeElement?.part.value === "native-li") {
                eventTarget.shadowRoot.querySelector("[part=delete-button]").focus();
            }
            else {
                eventTarget.focus();
            }
        }
    }
    _handleItemNavigation(e, tokens) {
        const isCtrl = !!(e.metaKey || e.ctrlKey);
        const target = e.target;
        if (isLeftCtrl(e) || isRightCtrl(e) || isDownCtrl(e) || isUpCtrl(e)) {
            return this._handleArrowCtrl(e, target, tokens, isRightCtrl(e) || isDownCtrl(e));
        }
        if (isLeftShift(e) || isRightShift(e) || isUpShift(e) || isDownShift(e) || isLeftShiftCtrl(e) || isRightShiftCtrl(e)) {
            e.preventDefault();
            return this._handleArrowShift(target, tokens, (isRightShift(e) || isRightShiftCtrl(e) || isDownShift(e)));
        }
        if (isHome(e) || isEnd(e) || isHomeCtrl(e) || isEndCtrl(e)) {
            e.preventDefault();
            return this._handleHome(tokens, isEnd(e) || isEndCtrl(e));
        }
        if (isCtrl && e.key.toLowerCase() === "a") {
            e.preventDefault();
            return this._toggleTokenSelection(tokens);
        }
        if (isLeft(e) || isRight(e) || isUp(e) || isDown(e)) {
            e.preventDefault();
            const nextTokenIdx = this._calcNextTokenIndex(this._tokens.find(token => token.focused), tokens, (isRight(e) || isDown(e)));
            this._scrollToToken(tokens[nextTokenIdx]);
        }
    }
    _handleHome(tokens, endKeyPressed) {
        if (!tokens || !tokens.length) {
            return -1;
        }
        const index = endKeyPressed ? tokens.length - 1 : 0;
        tokens[index].focus();
    }
    _handleHomeShift(e) {
        const tokens = this._tokens;
        const target = e.target;
        const currentTokenIdx = tokens.indexOf(target);
        const previousSelectedTokens = [...this._selectedTokens];
        tokens.filter((token, index) => index <= currentTokenIdx).forEach(token => {
            token.selected = true;
        });
        const selectedTokensChanged = JSON.stringify(previousSelectedTokens) !== JSON.stringify(this._selectedTokens);
        if (selectedTokensChanged) {
            this.fireEvent("selection-change", {
                tokens: this._selectedTokens,
            });
        }
        tokens[0].focus();
    }
    _handleEndShift(e) {
        const tokens = this._tokens;
        const target = e.target;
        const currentTokenIdx = tokens.indexOf(target);
        const previousSelectedTokens = [...this._selectedTokens];
        tokens.filter((token, index) => index >= currentTokenIdx).forEach(token => {
            token.selected = true;
        });
        const selectedTokensChanged = JSON.stringify(previousSelectedTokens) !== JSON.stringify(this._selectedTokens);
        if (selectedTokensChanged) {
            this.fireEvent("selection-change", {
                tokens: this._selectedTokens,
            });
        }
        tokens[tokens.length - 1].focus();
    }
    _calcNextTokenIndex(focusedToken, tokens, backwards) {
        if (!tokens.length) {
            return -1;
        }
        const focusedTokenIndex = tokens.indexOf(focusedToken);
        let nextIndex = backwards ? (focusedTokenIndex + 1) : (focusedTokenIndex - 1);
        if (nextIndex >= tokens.length) {
            nextIndex = tokens.length - 1;
        }
        if (nextIndex < 0) {
            nextIndex = 0;
        }
        return nextIndex;
    }
    _handleArrowCtrl(e, focusedToken, tokens, backwards) {
        const nextIndex = this._calcNextTokenIndex(focusedToken, tokens, backwards);
        e.preventDefault();
        if (nextIndex === -1) {
            return;
        }
        setTimeout(() => {
            tokens[nextIndex].focus();
        }, 0);
        this._scrollToToken(tokens[nextIndex]);
    }
    _handleArrowShift(focusedToken, tokens, backwards) {
        const focusedTokenIndex = tokens.indexOf(focusedToken);
        const nextIndex = backwards ? (focusedTokenIndex + 1) : (focusedTokenIndex - 1);
        const previousSelectedTokens = [...this._selectedTokens];
        if (nextIndex === -1 || nextIndex === tokens.length) {
            return;
        }
        focusedToken.selected = true;
        tokens[nextIndex].selected = true;
        const selectedTokensChanged = JSON.stringify(previousSelectedTokens) !== JSON.stringify(this._selectedTokens);
        if (selectedTokensChanged) {
            this.fireEvent("selection-change", {
                tokens: this._selectedTokens,
            });
        }
        tokens[nextIndex].focus();
        this._scrollToToken(tokens[nextIndex]);
    }
    _click(e) {
        if (e.metaKey || e.ctrlKey) {
            this.fireEvent("selection-change", {
                tokens: this._selectedTokens,
            });
            return;
        }
        const targetToken = e.target;
        if (!e.shiftKey) {
            this._previousToken = targetToken;
        }
        let focusedToken = targetToken;
        if (this._previousToken) {
            focusedToken = this._previousToken;
        }
        else {
            this._previousToken = focusedToken;
        }
        if (e.shiftKey) {
            const tokensArray = this._tokens;
            const lastClickedIndex = tokensArray.indexOf(targetToken);
            const firstSelectedTokenIndex = tokensArray.indexOf(focusedToken);
            const start = Math.min(lastClickedIndex, firstSelectedTokenIndex);
            const end = Math.max(lastClickedIndex, firstSelectedTokenIndex);
            if (lastClickedIndex !== -1) {
                tokensArray.forEach((token, i) => {
                    token.selected = i >= start && i <= end;
                });
            }
            this.fireEvent("selection-change", {
                tokens: this._selectedTokens,
            });
            return;
        }
        this._handleTokenSelection(e);
    }
    _onfocusin(e) {
        const target = e.target;
        this.open = false;
        this._itemNav.setCurrentItem(target);
        if (!this.expanded) {
            this.expanded = true;
        }
    }
    _onfocusout(e) {
        const relatedTarget = e.relatedTarget;
        this._tokens.forEach(token => {
            token.forcedTabIndex = "-1";
        });
        this._itemNav._currentIndex = -1;
        this._skipTabIndex = true;
        if (!this.contains(relatedTarget)) {
            this._tokens[0].forcedTabIndex = "0";
            this._skipTabIndex = false;
        }
        if (!this._tokenDeleting && !this._preventCollapse) {
            this._preventCollapse = false;
            this.expanded = false;
        }
    }
    _toggleTokenSelection(tokens) {
        if (!tokens || !tokens.length) {
            return;
        }
        const tokensAreSelected = tokens.every(token => token.selected);
        tokens.forEach(token => { token.selected = !tokensAreSelected; });
        this.fireEvent("selection-change", {
            tokens: this._selectedTokens,
        });
    }
    _handleTokenSelection(e, deselectAll = true) {
        const target = e.target;
        if (target.hasAttribute("ui5-token")) {
            const deselectTokens = deselectAll ? this._tokens : [];
            deselectTokens.forEach(token => {
                if (token !== target) {
                    token.selected = false;
                }
            });
            this.fireEvent("selection-change", {
                tokens: this._selectedTokens,
            });
        }
    }
    _fillClipboard(shortcutName, tokens) {
        const tokensTexts = tokens.filter(token => token.selected).map(token => token.text).join("\r\n");
        const cutToClipboard = (e) => {
            if (e.clipboardData) {
                e.clipboardData.setData("text/plain", tokensTexts);
            }
            e.preventDefault();
        };
        document.addEventListener(shortcutName, cutToClipboard);
        document.execCommand(shortcutName);
        document.removeEventListener(shortcutName, cutToClipboard);
    }
    /**
     * Scrolls the container of the tokens to its beginning.
     * This method is used by MultiInput and MultiComboBox.
     * @protected
     */
    scrollToStart() {
        if (this._scrollEnablement.scrollContainer) {
            this._scrollEnablement.scrollTo(0, 0);
        }
    }
    /**
     * Scrolls the container of the tokens to its end when expanded.
     * This method is used by MultiInput and MultiComboBox.
     * @protected
     */
    scrollToEnd() {
        const expandedTokenizerScrollWidth = this.contentDom && (this.effectiveDir !== "rtl" ? this.contentDom.scrollWidth : -this.contentDom.scrollWidth);
        if (this._scrollEnablement.scrollContainer) {
            this._scrollEnablement.scrollTo(expandedTokenizerScrollWidth, 0, 5, 10);
        }
    }
    /**
     * Scrolls token to the visible area of the container.
     * Adds 4 pixels to the scroll position to ensure padding and border visibility on both ends
     * @protected
     */
    _scrollToToken(token) {
        if (!this.contentDom) {
            return;
        }
        const tokenRect = token.getBoundingClientRect();
        const tokenContainerRect = this.contentDom.getBoundingClientRect();
        if (tokenRect.left < tokenContainerRect.left) {
            this._scrollEnablement.scrollTo(this.contentDom.scrollLeft - (tokenContainerRect.left - tokenRect.left + 5), 0);
        }
        else if (tokenRect.right > tokenContainerRect.right) {
            this._scrollEnablement.scrollTo(this.contentDom.scrollLeft + (tokenRect.right - tokenContainerRect.right + 5), 0);
        }
    }
    _getList() {
        return this.getPopover().querySelector("[ui5-list]");
    }
    get _tokens() {
        return this.getSlottedNodes("tokens");
    }
    get morePopoverOpener() {
        // return this.opener ? this : this.opener;
        if (this.opener) {
            return this.opener;
        }
        return this;
    }
    get _nMoreText() {
        if (!this._nMoreCount) {
            return;
        }
        if (this._getVisibleTokens().length) {
            return Tokenizer_1.i18nBundle.getText(MULTIINPUT_SHOW_MORE_TOKENS, this._nMoreCount);
        }
        return Tokenizer_1.i18nBundle.getText(TOKENIZER_SHOW_ALL_ITEMS, this._nMoreCount);
    }
    get showNMore() {
        return !this.expanded && !!this.overflownTokens.length;
    }
    get contentDom() {
        return this.shadowRoot.querySelector(".ui5-tokenizer--content");
    }
    get moreLink() {
        return this.shadowRoot.querySelector(".ui5-tokenizer-more-text");
    }
    get tokenizerLabel() {
        const effectiveLabelText = getEffectiveAriaLabelText(this);
        return effectiveLabelText || Tokenizer_1.i18nBundle.getText(TOKENIZER_ARIA_LABEL);
    }
    get tokenizerAriaDescription() {
        return getEffectiveAriaLabelText(this) ? Tokenizer_1.i18nBundle.getText(TOKENIZER_ARIA_LABEL) : undefined;
    }
    get _ariaDisabled() {
        return this.disabled || undefined;
    }
    get _ariaReadonly() {
        return this.readonly || undefined;
    }
    get morePopoverTitle() {
        return Tokenizer_1.i18nBundle.getText(TOKENIZER_POPOVER_REMOVE);
    }
    get overflownTokens() {
        if (!this.contentDom) {
            return [];
        }
        const tokensArray = this._tokens;
        // Reset the overflow prop of the tokens first in order
        // to use their dimensions for calculation because already
        // hidden tokens are set to 'display: none'
        tokensArray.forEach(token => {
            token.overflows = false;
        });
        return tokensArray.filter(token => {
            const parentRect = this.contentDom.getBoundingClientRect();
            const tokenRect = token.getBoundingClientRect();
            const tokenEnd = Number(tokenRect.right.toFixed(2));
            const parentEnd = Number(parentRect.right.toFixed(2));
            const tokenStart = Number(tokenRect.left.toFixed(2));
            const parentStart = Number(parentRect.left.toFixed(2));
            token.overflows = !this.expanded && ((tokenStart < parentStart) || (tokenEnd > parentEnd));
            return token.overflows;
        });
    }
    get _isPhone() {
        return isPhone();
    }
    get _selectedTokens() {
        return this._tokens.filter(token => token.selected);
    }
    get _nMoreListMode() {
        if (this.readonly || this.disabled) {
            return ListSelectionMode.None;
        }
        return ListSelectionMode.Delete;
    }
    get styles() {
        return {
            popover: {
                "min-width": this.popoverMinWidth ? `${this.popoverMinWidth}px` : `${this.getBoundingClientRect().width}px`,
            },
        };
    }
    /**
     * @protected
     */
    _focusLastToken() {
        const tokens = this._tokens;
        if (tokens.length === 0) {
            return;
        }
        const lastToken = tokens[tokens.length - 1];
        lastToken.focus();
    }
    static async onDefine() {
        Tokenizer_1.i18nBundle = await getI18nBundle("@ui5/webcomponents");
    }
    getPopover() {
        return this.shadowRoot.querySelector("[ui5-responsive-popover]");
    }
};
__decorate([
    property({ type: Boolean })
], Tokenizer.prototype, "readonly", void 0);
__decorate([
    property({ type: Boolean })
], Tokenizer.prototype, "disabled", void 0);
__decorate([
    property()
], Tokenizer.prototype, "accessibleName", void 0);
__decorate([
    property()
], Tokenizer.prototype, "accessibleNameRef", void 0);
__decorate([
    property({ type: Boolean })
], Tokenizer.prototype, "expanded", void 0);
__decorate([
    property({ type: Boolean })
], Tokenizer.prototype, "open", void 0);
__decorate([
    property({
        converter: DOMReferenceConverter,
    })
], Tokenizer.prototype, "opener", void 0);
__decorate([
    property({ type: Number })
], Tokenizer.prototype, "popoverMinWidth", void 0);
__decorate([
    property({ type: Boolean })
], Tokenizer.prototype, "preventInitialFocus", void 0);
__decorate([
    property({ type: Boolean })
], Tokenizer.prototype, "preventPopoverOpen", void 0);
__decorate([
    property({ type: Boolean })
], Tokenizer.prototype, "hidePopoverArrow", void 0);
__decorate([
    property({ type: Number })
], Tokenizer.prototype, "_nMoreCount", void 0);
__decorate([
    property({ type: Number })
], Tokenizer.prototype, "_tokensCount", void 0);
__decorate([
    slot({
        type: HTMLElement,
        "default": true,
        individualSlots: true,
        invalidateOnChildChange: {
            properties: ["_isVisible"],
            slots: false,
        },
    })
], Tokenizer.prototype, "tokens", void 0);
Tokenizer = Tokenizer_1 = __decorate([
    customElement({
        tag: "ui5-tokenizer",
        languageAware: true,
        renderer: litRender,
        template: TokenizerTemplate,
        styles: [
            TokenizerCss,
            ResponsivePopoverCommonCss,
            SuggestionsCss,
            TokenizerPopoverCss,
        ],
        dependencies: [
            ResponsivePopover,
            List,
            ListItemStandard,
            Title,
            Button,
            Icon,
        ],
    })
    /**
     * Fired when tokens are being deleted (delete icon, delete or backspace is pressed)
     * @param {Array} tokens An array containing the deleted tokens.
     * @public
     */
    ,
    event("token-delete", {
        detail: {
            /**
            * @public
            */
            tokens: { type: Array },
        },
    })
    /**
     * Fired when token selection is changed by user interaction
     *
     * @param {Array} tokens An array of the selected items.
     * @public
     */
    ,
    event("selection-change", {
        detail: {
            tokens: { type: Array },
        },
    })
    /**
     * Fired when nMore link is pressed.
     * @private
     */
    ,
    event("show-more-items-press")
    /**
     * Fired before nMore Popover is opened.
     * @private
     */
    ,
    event("before-more-popover-open")
], Tokenizer);
const getTokensCountText = (iTokenCount) => {
    const tokenCountMap = {
        0: TOKENIZER_ARIA_CONTAIN_TOKEN,
        1: TOKENIZER_ARIA_CONTAIN_ONE_TOKEN,
    };
    if (iTokenCount in tokenCountMap) {
        return Tokenizer.i18nBundle.getText(tokenCountMap[iTokenCount]);
    }
    return Tokenizer.i18nBundle.getText(TOKENIZER_ARIA_CONTAIN_SEVERAL_TOKENS, iTokenCount);
};
Tokenizer.define();
export default Tokenizer;
export { getTokensCountText };
export { ClipboardDataOperation };
//# sourceMappingURL=Tokenizer.js.map




© 2015 - 2024 Weber Informatics LLC | Privacy Policy