UNPKG

@progress/kendo-react-dropdowns

Version:

React DropDowns offer an interface for users to select different items from a list and more. KendoReact Dropdowns package

704 lines (703 loc) • 32.5 kB
/** * @license *------------------------------------------------------------------------------------------- * Copyright © 2025 Progress Software Corporation. All rights reserved. * Licensed under commercial license. See LICENSE.md in the package root for more information *------------------------------------------------------------------------------------------- */ import * as f from "react"; import m from "prop-types"; import { Keys as u, classNames as I, IconWrap as L, WatermarkOverlay as J, getLicenseMessage as Q, canUseDOM as B, validatePackage as X, createPropsContext as Z, withIdHOC as ee, withPropsContext as te, withAdaptiveModeContext as se, kendoThemeMaps as ie } from "@progress/kendo-react-common"; import { plusIcon as oe } from "@progress/kendo-svg-icons"; import { FloatingLabel as ae } from "@progress/kendo-react-labels"; import ne from "../common/ListContainer.mjs"; import le from "../common/List.mjs"; import de from "../common/GroupStickyHeader.mjs"; import re from "./TagList.mjs"; import he from "../common/SearchBar.mjs"; import M from "../common/DropDownBase.mjs"; import { ActiveDescendant as w } from "../common/settings.mjs"; import { getFilteredData as b, areSame as E, removeDataItems as T, isPresent as O, getItemValue as P, preventDefaultNonInputs as pe, matchTags as V, itemIndexStartsWith as ce } from "../common/utils.mjs"; import { packageMetadata as z } from "../package-metadata.mjs"; import ue from "../common/ClearButton.mjs"; import { AdaptiveMode as fe } from "../common/AdaptiveMode.mjs"; import { ActionSheetContent as ge } from "@progress/kendo-react-layout"; import me from "../common/ListFilter.mjs"; import A from "../common/withCustomComponent.mjs"; const { sizeMap: D, roundedMap: ve } = ie, be = "Please enter a valid value!", H = (F) => F.preventDefault(), W = (F) => F === 2, y = class y extends f.Component { constructor(n) { super(n), this.state = { activedescendant: w.PopupList, currentValue: [] }, this._element = null, this._valueItemsDuringOnChange = null, this.base = new M(this), this._tags = [], this._input = null, this._adaptiveInput = null, this._skipFocusEvent = !1, this._lastSelectedOrDeslectedItemIndex = null, this.itemHeight = 0, this.scrollToFocused = !1, this.showLicenseWatermark = !1, this.focus = () => { this._input && this._input.focus(); }, this.handleItemSelect = (e, t) => { const { dataItemKey: a, virtual: s } = this.props, o = b(this.props), p = s ? s.skip : 0, c = o[e - p], r = this.value.findIndex((g) => E(g, c, a)); this._lastSelectedOrDeslectedItemIndex = o.findIndex((g) => E(g, c, a)); let i = []; r !== -1 ? (i = this.value, i.splice(r, 1)) : i = [...this.value, c], (this.props.filter !== void 0 ? this.props.filter : this.state.text) && !this.mobileMode && (this.state.text && (t.data.text = ""), this.base.filterChanged("", t)), this._adaptiveInput && this._adaptiveInput.blur(), this.state.focusedIndex !== void 0 && (t.data.focusedIndex = void 0), this.triggerOnChange(i, t), this.base.triggerPageChangeCornerItems(c, t); }, this.onTagDelete = (e, t) => { const a = this.base.initState(); a.syntheticEvent = t, this.opened && this.base.togglePopup(a), !this.state.focused && !this.mobileMode && (a.data.focused = !0, this.focus()); const s = this.value; T(s, e, this.props.dataItemKey), this.triggerOnChange(s, a), this.applyState(a); }, this.itemFocus = (e, t) => { const { allowCustom: a, virtual: s } = this.props, o = b(this.props), p = s ? s.skip : 0, c = this.props.filter !== void 0 ? this.props.filter : this.state.text, { focusedIndex: r } = this.getFocusedState(), i = a && c, l = o[e - p]; l && r !== e ? this.state.focusedIndex !== e && (t.data.focusedIndex = e, t.data.activedescendant = w.PopupList) : i && e === -1 && this.state.focusedIndex !== void 0 && (t.data.focusedIndex = void 0), this.base.triggerPageChangeCornerItems(l, t); }, this.componentRef = (e) => { this._element = e, this.base.wrapper = e; }, this.searchbarRef = (e) => { const t = this._input = e && e.input; t && this.state.focused && window.setTimeout(() => t.focus(), 0); }, this.onChangeHandler = (e) => { const t = this.base.initState(), a = e.target.value; t.syntheticEvent = e, this.props.filter === void 0 && (t.data.text = a), t.data.focusedIndex = void 0, this.opened || (this.base.togglePopup(t), this.setState({ currentValue: this.value })), this.base.filterChanged(a, t), this.applyState(t), this.setState({ group: void 0 }); }, this.clearButtonClick = (e) => { const t = this.base.initState(); t.syntheticEvent = e, e.stopPropagation(), this.value.length > 0 && this.triggerOnChange([], t), this.state.focusedIndex !== void 0 && (t.data.focusedIndex = void 0), this.opened && this.base.togglePopup(t); const a = this.props.filter !== void 0 ? this.props.filter : this.state.text; O(a) && a !== "" && this.base.filterChanged("", t), this.state.text && (t.data.text = ""), this._lastSelectedOrDeslectedItemIndex = null, this.applyState(t); }, this.onInputKeyDown = (e) => { const { textField: t, groupField: a } = this.props, s = b(this.props), o = e.keyCode, p = this.props.filter !== void 0 ? this.props.filter : this.state.text, c = this.props.opened !== void 0 ? this.props.opened : this.state.opened, { focusedItem: r, focusedIndex: i } = this.getFocusedState(), l = this.base.initState(); if (l.syntheticEvent = e, !p && this.value.length > 0 && (o === u.left || o === u.right || o === u.home || o === u.end || o === u.delete || o === u.backspace) && !e.shiftKey) return this.onTagsNavigate(e, l); const g = () => { e.preventDefault(), this.base.togglePopup(l), this.applyState(l); }; if (this.opened) if (o === u.pageUp) e.preventDefault(), this.base.scrollPopupByPageSize(-1); else if (o === u.pageDown) e.preventDefault(), this.base.scrollPopupByPageSize(1); else if ((e.ctrlKey || e.metaKey) && e.code === "KeyA") { const h = (this.state.value && this.state.value.length) === s.length ? [] : s; this.updateStateOnKeyboardNavigation(h, l); } else if ((e.ctrlKey || e.metaKey) && e.shiftKey && e.keyCode === u.end) { const d = s.slice(this.getFocusedState().focusedIndex); this.itemFocus(s.length - 1, l), this.updateStateOnKeyboardNavigation(d, l); } else if ((e.ctrlKey || e.metaKey) && e.shiftKey && e.keyCode === u.home) { const d = s.slice(0, this.getFocusedState().focusedIndex + 1); this.itemFocus(0, l), this.updateStateOnKeyboardNavigation(d, l); } else if (e.shiftKey && e.keyCode === u.up) { let d; const h = this.getLastSelectedOrDeselectedIndex(1, i); h === null ? d = i !== 0 ? s.slice(i - 1, i) : [s[i]] : h === i ? d = [s[h - 1]] : i >= 0 && (d = h > i ? s.slice(i - 1, h) : s.slice(h - 1, i)), d && d.length > 0 && (i >= 1 && this.itemFocus(i - 1, l), this.updateStateOnKeyboardNavigation(d, l)); } else if (e.shiftKey && e.keyCode === u.down) { let d; const h = this.getLastSelectedOrDeselectedIndex(0, i); h === null ? d = i !== s.length - 1 ? s.slice(i, i + 1) : [s[i]] : h === i ? d = s.slice(i, i + 2) : i >= 0 && (d = h > i ? s.slice(i + 1, h + 1) : s.slice(h, i + 2)), d && d.length >= 1 && (this.itemFocus(i + 1, l), this.updateStateOnKeyboardNavigation(d, l)); } else if (e.altKey && o === u.up) g(); else if (o === u.up || o === u.down) { if (a !== "" && t) if (!this.props.skipDisabledItems && c) this.onNavigate(l, o); else { let d = 0; if (o === u.down || o === u.right) { const h = s.slice(i + 1).find((v) => !v.disabled && v[t]); d = h && s.findIndex((v) => v[t] === h[t]); } else if (o === u.up || o === u.left) { let h; if (i === -1) h = s, d = s.findIndex((v) => !v.disabled && v[t]); else { h = s.slice(0, i); let v = h.pop(); for (; v && v.disabled; ) v = h.pop(); d = v && s.findIndex((x) => x[t] === v[t]); } } if (d) { const h = d - i; this.onNavigate(l, o, h); } else d !== void 0 && this.onNavigate(l, o); } else if (!this.props.skipDisabledItems && c) this.onNavigate(l, o); else { let d = null; if (o === u.down || o === u.right) d = s.slice(i + 1).find((h) => !h.disabled); else if (o === u.up || o === u.left) { const h = s.slice(0, i); for (d = h.pop(); d && d.disabled; ) d = h.pop(); } if (d) { const h = d.id - i - 1; this.onNavigate(l, o, h); } else this.onNavigate(l, o); } this.applyState(l), e.preventDefault(); } else o === u.enter ? (e.preventDefault(), this.props.allowCustom && p && r === null ? this.customItemSelect(e) : r && r.disabled ? g() : this.selectFocusedItem(e)) : o === u.esc && g(); else e.altKey && o === u.down ? g() : o === u.esc && this.clearButtonClick(e); }, this.listContainerContent = () => { const { header: e, footer: t, allowCustom: a, size: s, groupStickyHeaderItemRender: o, groupField: p, list: c } = this.props, r = b(this.props), i = this.props.filter !== void 0 ? this.props.filter : this.state.text, { focusedType: l } = this.getFocusedState(), g = a && i && /* @__PURE__ */ f.createElement( "div", { className: I("k-list", { [`k-list-${D[s] || s}`]: s }), key: "customitem", onClick: this.customItemSelect, onMouseDown: H }, /* @__PURE__ */ f.createElement( "div", { className: I("k-list-item k-custom-item", { "k-focus": W(l) }), style: { fontStyle: "italic" } }, i, /* @__PURE__ */ f.createElement(L, { name: "plus", icon: oe, style: { position: "absolute", right: "0.5em" } }) ) ); let { group: d } = this.state; return d === void 0 && p !== void 0 && (d = P(r[0], p)), /* @__PURE__ */ f.createElement(f.Fragment, null, e && /* @__PURE__ */ f.createElement("div", { className: "k-list-header" }, e), g, /* @__PURE__ */ f.createElement( "div", { className: I("k-list", { [`k-list-${this.mobileMode ? "lg" : D[s] || s}`]: s, "k-virtual-list": this.base.vs.enabled }) }, !c && d && r.length !== 0 && /* @__PURE__ */ f.createElement(de, { group: d, groupMode: "modern", render: o }), this.renderList() ), this.showLicenseWatermark && /* @__PURE__ */ f.createElement(J, { message: this.licenseMessage }), t && /* @__PURE__ */ f.createElement("div", { className: "k-list-footer" }, t)); }, this.renderListContainer = () => { const e = this.base, { dir: t } = this.props, a = b(this.props), s = this.base.getPopupSettings(), o = s.width !== void 0 ? s.width : e.popupWidth, p = { dir: t !== void 0 ? t : e.dirCalculated, width: o, popupSettings: { ...s, popupClass: I(s.popupClass, "k-list-container", "k-multiselect-popup"), anchor: s.anchor || this.element, show: this.opened, onOpen: this.onPopupOpened, onClose: this.onPopupClosed }, itemsCount: [a.length, this.value.length] }; return /* @__PURE__ */ f.createElement(ne, { ...p }, this.listContainerContent()); }, this.renderAdaptiveListContainer = () => { const { adaptiveTitle: e, adaptiveSubtitle: t, filterable: a, filter: s } = this.props, { windowWidth: o = 0 } = this.state, p = s !== void 0 ? s : this.state.text, c = a ? /* @__PURE__ */ f.createElement( me, { value: p, ref: (i) => { this._adaptiveInput = i && i.element; }, onChange: this.onChangeHandler, onKeyDown: this.onInputKeyDown, size: "large", rounded: this.props.rounded, fillMode: this.props.fillMode, placeholder: this.props.placeholder } ) : null, r = { title: e || this.props.label, subTitle: t, expand: this.opened, onClose: (i) => this.closePopup(i), windowWidth: o, mobileFilter: c }; return /* @__PURE__ */ f.createElement(fe, { ...r }, /* @__PURE__ */ f.createElement(ge, null, /* @__PURE__ */ f.createElement("div", { className: "k-list-container" }, this.listContainerContent()))); }, this.closePopup = (e) => { const t = this.base.initState(); t.syntheticEvent = e, e.stopPropagation(), this.state.focusedIndex !== void 0 && (t.data.focusedIndex = void 0), this.opened && this.base.togglePopup(t), t.events.push({ type: "onClose" }); const a = this.props.filter !== void 0 ? this.props.filter : this.state.text; O(a) && a !== "" && this.base.filterChanged("", t), this.state.text && (t.data.text = ""), this.applyState(t); }, this.onCancel = (e) => { const t = this.base.initState(); t.syntheticEvent = e, e.stopPropagation(), this.state.focusedIndex !== void 0 && (t.data.focusedIndex = void 0), this.opened && this.base.togglePopup(t), t.events.push({ type: "onCancel" }); const a = this.props.filter !== void 0 ? this.props.filter : this.state.text; O(a) && a !== "" && this.base.filterChanged("", t), this.state.text && (t.data.text = ""), this.applyState(t); }, this.renderList = () => { const { textField: e, listNoDataRender: t, itemRender: a, groupHeaderItemRender: s, dataItemKey: o, virtual: p = { skip: 0, total: void 0 } } = this.props, c = b(this.props), r = this.base.vs, { focusedIndex: i } = this.getFocusedState(), l = this.base.getPopupSettings(), g = `translateY(${r.translate}px)`; return /* @__PURE__ */ f.createElement( le, { id: this.base.listBoxId, show: this.opened, data: c.slice(), focusedIndex: i - p.skip, value: this.value, textField: e, valueField: o, optionsGuid: this.base.guid, groupField: this.props.groupField, groupMode: "modern", listRef: (d) => { r.list = this.base.list = d; }, wrapperStyle: this.mobileMode ? {} : { maxHeight: l.height }, wrapperCssClass: "k-list-content", listStyle: r.enabled ? { transform: g } : void 0, key: "listKey", skip: p.skip, onClick: this.handleItemClick, itemRender: a, groupHeaderItemRender: s, noDataRender: t, onMouseDown: H, onBlur: this.handleBlur, onScroll: this.onScroll, wrapperRef: r.scrollerRef, scroller: this.base.renderScrollElement(), ariaSetSize: p.total } ); }, this.onScroll = (e) => { const { vs: t, list: a } = this.base; t.scrollHandler(e); const { groupField: s } = this.props; let o = b(this.props); if (!(!s || !o.length) && s) { const p = this.itemHeight = this.itemHeight || (t.enabled ? t.itemHeight : a ? a.children[0].offsetHeight : 0), r = e.target.scrollTop - t.skip * p; o = this.base.getGroupedDataModernMode(o, s); let i = o[0][s]; for (let l = 1; l < o.length && !(p * l > r); l++) o[l] && o[l][s] && (i = o[l][s]); i !== this.state.group && this.setState({ group: i }); } }, this.customItemSelect = (e) => { const t = this.props.filter !== void 0 ? this.props.filter : this.state.text, { textField: a } = this.props; if (!t) return; const s = this.base.initState(); s.syntheticEvent = e; const o = a ? { [a]: t } : t; this.state.text !== void 0 && (s.data.text = ""), s.data.focusedIndex = void 0, this.base.filterChanged("", s); const p = [...this.value, o]; this.triggerOnChange(p, s), this.base.togglePopup(s), this.applyState(s); }, this.handleWrapperClick = (e) => { const t = this._input; !this.opened && t && this.focusElement(t); const a = this.base.initState(); a.syntheticEvent = e, !this.state.focused && !this.mobileMode && (a.events.push({ type: "onFocus" }), a.data.focused = !0), this.mobileMode && (this.setState({ currentValue: this.tagsToRender }), this.mobileMode && window.setTimeout(() => this._adaptiveInput && this._adaptiveInput.focus(), 300)), this.base.togglePopup(a), this.applyState(a); }, this.handleItemClick = (e, t) => { const a = this.base.initState(); a.syntheticEvent = t, this.handleItemSelect(e, a), this.props.autoClose && this.base.togglePopup(a), t.stopPropagation(), this.applyState(a); }, this.handleBlur = (e) => { if (!this.state.focused || this._skipFocusEvent) return; const t = this.base.initState(), { allowCustom: a, filterable: s } = this.props; t.syntheticEvent = e, t.data.focused = !1, t.events.push({ type: "onBlur" }), this.opened && !this.mobileMode && (this.state.opened && (t.data.opened = !1), t.events.push({ type: "onClose" })), !a && !s && this.state.text && (t.data.text = ""), this.applyState(t); }, this.handleFocus = (e) => { this._skipFocusEvent || this.base.handleFocus(e); }, this.onPopupOpened = () => { this._input && this.state.focused && !this.mobileMode && this.focusElement(this._input); }, this.onPopupClosed = () => { this.state.focused && window.setTimeout(() => { this.state.focused && this.focusElement(this._input); }, 0); }, this.setValidity = () => { this._input && this._input.setCustomValidity && this._input.setCustomValidity( this.validity.valid ? "" : this.props.validationMessage || be ); }, this.validate(n), this.licenseMessage = Q(z); } get _inputId() { return this.props.id; } get document() { if (B) return this.element && this.element.ownerDocument || document; } validate(n) { if (n.filterable || n.virtual) { const e = []; n.filterable && e.push("filterable"), n.virtual && e.push("virtualization"), this.showLicenseWatermark = !X(z, { component: "MultiSelect", features: e }); } } /** @hidden */ get element() { return this._element; } /** @hidden */ get opened() { return !!(this.props.opened !== void 0 ? this.props.opened : this.state.opened); } /** @hidden */ get tagsToRender() { const { tags: n, textField: e } = this.props, t = []; return n === void 0 ? this.value.forEach((a) => { t.push({ text: P(a, e), data: [a] }); }) : t.push(...n), t; } /** * The mobile mode of the MultiSelect. */ get mobileMode() { var e; return !!(this.state.windowWidth && this.props._adaptiveMode && this.state.windowWidth <= ((e = this.props._adaptiveMode) == null ? void 0 : e.medium) && this.props.adaptive); } /** * Represents the value of the MultiSelect. */ get value() { const n = []; return this._valueItemsDuringOnChange ? n.push(...this._valueItemsDuringOnChange) : this.props.value ? n.push(...this.props.value) : this.state.value ? n.push(...this.state.value) : this.props.defaultValue && n.push(...this.props.defaultValue), n; } /** * Gets the `name` property of the MultiSelect. */ get name() { return this.props.name; } /** * Represents the validity state into which the MultiSelect is set. */ get validity() { const n = this.props.validationMessage !== void 0, e = !this.required || this.value !== null && this.value.length > 0 && this.value !== void 0, t = this.props.valid !== void 0 ? this.props.valid : e; return { customError: n, valid: t, valueMissing: this.value === null }; } /** @hidden */ get required() { return this.props.required !== void 0 ? this.props.required : y.defaultProps.required; } get validityStyles() { return this.props.validityStyles !== void 0 ? this.props.validityStyles : y.defaultProps.validityStyles; } /** @hidden */ componentDidUpdate(n, e) { var g; const { virtual: t, groupField: a = "" } = this.props, s = b(this.props), o = t ? t.skip : 0, p = n.virtual ? n.virtual.total : 0, c = n.opened !== void 0 ? n.opened : e.opened, r = !c && this.opened, i = c && !this.opened, l = this.base.getPopupSettings(); if (this.validate(this.props), this.base.didUpdate(), !l.animate && i && this.onPopupClosed(), t && t.total !== p) this.base.vs.calcScrollElementHeight(), this.base.vs.reset(); else { let { focusedItem: d, focusedIndex: h } = this.getFocusedState(); a !== "" && (h = (g = this.base.getGroupedDataModernMode(s, a)) == null ? void 0 : g.indexOf(d)), r && t ? this.base.scrollToVirtualItem(t, h - o) : r && !t ? (s && s.length !== 0 && this.base.resetGroupStickyHeader(s[0][a], this), this.base.scrollToItem(h)) : this.opened && c && d && this.scrollToFocused && this.base.scrollToItem(h - o); } this.scrollToFocused = !1, this.setValidity(); } /** @hidden */ componentDidMount() { var n; this.observerResize = B && window.ResizeObserver && new window.ResizeObserver(this.calculateMedia.bind(this)), this.base.didMount(), this.setValidity(), (n = this.document) != null && n.body && this.observerResize && this.observerResize.observe(this.document.body); } /** @hidden */ componentWillUnmount() { var n; (n = this.document) != null && n.body && this.observerResize && this.observerResize.disconnect(); } /** @hidden */ onNavigate(n, e, t) { const { allowCustom: a } = this.props, s = b(this.props), o = this.props.filter !== void 0 ? this.props.filter : this.state.text, { focusedType: p, focusedIndex: c } = this.getFocusedState(), r = a && o, i = W(p), l = this.base, g = l.vs; if (this.opened && e === u.up && i) this.state.focusedIndex !== void 0 && (n.data.focusedIndex = void 0); else { const d = l.navigation.navigate({ keyCode: e, current: c, max: (g.enabled ? g.total : s.length) - 1, min: r ? -1 : 0, skipItems: t || void 0 }); d !== void 0 && (this.itemFocus(d, n), this.scrollToFocused = !0); } this.applyState(n); } /** @hidden */ render() { const { style: n, className: e, label: t, dir: a, disabled: s, textField: o, dataItemKey: p, virtual: c, size: r, rounded: i, fillMode: l, loading: g, filter: d } = this.props, { text: h, focused: v, focusedTag: x, currentValue: $ } = this.state, C = this.base.vs, K = this.props.id || this._inputId; C.enabled = c !== void 0, c !== void 0 && (C.skip = c.skip, C.total = c.total, C.pageSize = c.pageSize); const S = this.mobileMode && this.opened ? $ : this.tagsToRender; this.setItems(this.tagsToRender, this._tags); const N = !this.validityStyles || this.validity.valid, q = !!(d !== void 0 ? d : h) || S && S.length > 0, [G, U] = A(this.props.prefix || f.Fragment), [j, Y] = A(this.props.suffix || f.Fragment), R = /* @__PURE__ */ f.createElement(f.Fragment, null, /* @__PURE__ */ f.createElement( "div", { ref: this.componentRef, className: I("k-multiselect k-input", e, { [`k-input-${D[r] || r}`]: r, [`k-rounded-${ve[i] || i}`]: i, [`k-input-${l}`]: l, "k-focus": v && !s, "k-invalid": !N, "k-disabled": s, "k-loading": g, "k-required": this.required }), style: t ? { ...n, width: void 0 } : n, dir: a, onFocus: (k) => { this.mobileMode ? this.handleWrapperClick(k) : this.handleFocus(k); }, onBlur: this.handleBlur, onClick: this.handleWrapperClick, onMouseDown: pe }, this.props.prefix && /* @__PURE__ */ f.createElement(G, { ...U }), /* @__PURE__ */ f.createElement("div", { className: I("k-input-values") }, /* @__PURE__ */ f.createElement( "div", { className: I("k-chip-list", { [`k-chip-list-${D[r] || r}`]: r }), role: "listbox", id: "tagslist-" + this.base.guid }, S && S.length > 0 && /* @__PURE__ */ f.createElement( re, { tagRender: this.props.tagRender, onTagDelete: this.onTagDelete, data: S, guid: this.base.guid, focused: x ? S.find((k) => V(k, x, p)) : void 0, size: r } ) ), this.renderSearchBar(K)), g && /* @__PURE__ */ f.createElement(L, { className: "k-input-loading-icon", name: "loading" }), this.props.suffix && /* @__PURE__ */ f.createElement(j, { ...Y }), q && /* @__PURE__ */ f.createElement(ue, { onClick: this.clearButtonClick }), !this.mobileMode && this.renderListContainer() ), this.mobileMode && this.renderAdaptiveListContainer()); return t ? /* @__PURE__ */ f.createElement( ae, { label: t, editorId: K, editorValue: h || P(this.value[0], o), editorValid: N, editorDisabled: s, style: { width: n ? n.width : void 0 }, children: R } ) : R; } renderSearchBar(n) { const { activedescendant: e, focusedTag: t, currentValue: a } = this.state, { disabled: s, placeholder: o, ariaDescribedBy: p, ariaLabelledBy: c, ariaLabel: r, inputAttributes: i } = this.props, l = !this.mobileMode && (this.props.filter !== void 0 ? this.props.filter : this.state.text) || "", { focusedIndex: g } = this.getFocusedState(), d = this.value.length === 0 && !l ? o : void 0, h = a && a.length > 0 ? void 0 : o, v = e === w.TagsList && t !== void 0 ? `tag-${this.base.guid}-${t.text.replace(/\s+/g, "-")}` : `option-${this.base.guid}-${g}`, x = { accessKey: this.props.accessKey, tabIndex: this.props.tabIndex }; return /* @__PURE__ */ f.createElement( he, { id: n, size: Math.max((d || "").length, l.length, 1), placeholder: this.mobileMode && this.opened ? h : d, value: l, onChange: this.onChangeHandler, onKeyDown: this.onInputKeyDown, ref: this.searchbarRef, disabled: s, expanded: this.opened, owns: this.base.listBoxId, role: "combobox", activedescendant: v, ariaDescribedBy: `tagslist-${this.base.guid}${p ? " " + p : ""}`, ariaLabelledBy: c, ariaRequired: this.required, ariaLabel: r, inputAttributes: i, ...x } ); } onTagsNavigate(n, e) { const t = n.keyCode, { focusedTag: a } = this.state, s = this._tags, o = this.props.dataItemKey; let p = a ? s.findIndex((i) => V(i, a, o)) : -1, c; const r = p !== -1; if (t === u.left) r ? p = Math.max(0, p - 1) : p = s.length - 1, c = s[p]; else if (t === u.right) p === s.length - 1 ? c = void 0 : r && (p = Math.min(s.length - 1, p + 1), c = s[p]); else if (t === u.home && !n.shiftKey) c = s[0]; else if (t === u.end && !n.shiftKey) c = s[s.length - 1]; else if (t === u.delete) { if (r) { const i = this.value; T(i, s[p].data, o), this.triggerOnChange(i, e); } } else if (t === u.backspace) { const i = this.value; if (r) T(i, s[p].data, o), this.triggerOnChange(i, e); else if (!r && s.length) { const l = s.pop(); T(i, l.data, o), this.triggerOnChange(i, e); } } c !== a && (e.data.focusedTag = c, e.data.activedescendant = w.TagsList), this.applyState(e); } triggerOnChange(n, e) { this.props.value === void 0 && (e.data.value = [...n]), this._valueItemsDuringOnChange = [], this.setItems(n, this._valueItemsDuringOnChange), e.events.push({ type: "onChange" }); } selectFocusedItem(n, e) { const { virtual: t } = this.props, a = b(this.props), { focusedIndex: s } = e || this.getFocusedState(), o = t ? t.skip : 0; a[s - o] !== void 0 && this.handleItemClick(s, n); } setItems(n, e) { e.length = 0, e.push(...n); } getFocusedState() { const { focusedIndex: n } = this.state, e = this.props.filter !== void 0 ? this.props.filter : this.state.text, { allowCustom: t, dataItemKey: a, virtual: s, textField: o, focusedItemIndex: p = ce, skipDisabledItems: c } = this.props, r = b(this.props), i = s && s.skip || 0; let l; if (n !== void 0) return { focusedIndex: n, focusedItem: r[n - i], focusedType: 1 /* ListItem */ }; const g = this.value; if (t && e) return { focusedItem: null, focusedIndex: -1, focusedType: 2 /* CustomItem */ }; if (e) return l = p(r, e, o), { focusedItem: r[l], focusedIndex: l + i, focusedType: 1 /* ListItem */ }; if (g.length) { const d = g[g.length - 1]; return l = r.findIndex((h) => E(h, d, a)), r[l] !== void 0 ? { focusedIndex: l + i, focusedItem: r[l], focusedType: 1 /* ListItem */ } : { focusedType: 0, focusedIndex: -1 }; } else if (c && o && !e && i === 0) { const d = r.findIndex((h) => !h.disabled && h[o]); return { focusedIndex: d, focusedItem: r[d - i], focusedType: 1 /* ListItem */ }; } return i === 0 ? { focusedItem: r[0], focusedIndex: 0, focusedType: 1 /* ListItem */ } : { focusedType: 0, focusedIndex: -1 }; } focusElement(n) { this._skipFocusEvent = !0, n.focus(), window.setTimeout(() => this._skipFocusEvent = !1, 0); } applyState(n) { this.base.applyState(n), this._valueItemsDuringOnChange = null; } calculateMedia(n) { for (const e of n) this.setState({ windowWidth: e.target.clientWidth }); } /** * Updates the state of the MultiSelect when the complex keyboard navigation that * includes key combinations with the Ctrl/Command, Shift, Home and End keys * * @param {Array<string | Object>} dataToSet Defines the array of new values that will be applied to the MultiSelect * @param {MultiSelectInternalState} state The current state of the MultiSelect */ updateStateOnKeyboardNavigation(n, e) { this.setState({ value: n }), this.triggerOnChange(n, e), this.applyState(e); } /** * Returns the last element that was selected or deselected. Needed for the keyboard navigation specifications * * @param {number} correction A correction is needed depending on if UP or DOWN key is pressed */ getLastSelectedOrDeselectedIndex(n, e) { return this._lastSelectedOrDeslectedItemIndex === null && (this._lastSelectedOrDeslectedItemIndex = e), this._lastSelectedOrDeslectedItemIndex !== null ? this._lastSelectedOrDeslectedItemIndex + n : null; } }; y.displayName = "MultiSelect", y.propTypes = { ...M.propTypes, autoClose: m.bool, value: m.arrayOf(m.any), defaultValue: m.arrayOf(m.any), dataItemKey: m.string, placeholder: m.string, tags: m.arrayOf( m.shape({ text: m.string, data: m.arrayOf(m.any) }) ), tagRender: m.func, id: m.string, ariaLabelledBy: m.string, ariaDescribedBy: m.string, groupField: m.string, list: m.any, adaptive: m.bool, adaptiveTitle: m.string, adaptiveSubtitle: m.string, onCancel: m.func, skipDisabledItems: m.bool, inputAttributes: m.object }, y.defaultProps = { ...M.defaultProps, autoClose: !0, required: !1, size: "medium", rounded: "medium", fillMode: "solid", groupMode: "modern", skipDisabledItems: !0, prefix: void 0, suffix: void 0 }; let _ = y; const Ie = Z(), ye = ee( te( Ie, se(_) ) ); ye.displayName = "KendoReactMultiSelect"; export { ye as MultiSelect, Ie as MultiSelectPropsContext, _ as MultiSelectWithoutContext };