@progress/kendo-react-dropdowns
Version:
React DropDowns offer an interface for users to select different items from a list and more. KendoReact Dropdowns package
717 lines (716 loc) • 33.1 kB
JavaScript
/**
* @license
*-------------------------------------------------------------------------------------------
* Copyright © 2026 Progress Software Corporation. All rights reserved.
* Licensed under commercial license. See LICENSE.md in the package root for more information
*-------------------------------------------------------------------------------------------
*/
import * as g from "react";
import v from "prop-types";
import { Keys as u, classNames as S, IconWrap as B, WatermarkOverlay as J, getLicenseMessage as Q, canUseDOM as V, 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 O from "../common/DropDownBase.mjs";
import { ActiveDescendant as w } from "../common/settings.mjs";
import { getFilteredData as x, areSame as P, removeDataItems as D, isPresent as _, getItemValue as K, preventDefaultNonInputs as pe, matchTags as z, itemIndexStartsWith as ce } from "../common/utils.mjs";
import { packageMetadata as A } 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 H from "../common/withCustomComponent.mjs";
const { sizeMap: M, roundedMap: ve } = ie, be = "Please enter a valid value!", W = (E) => E.preventDefault(), $ = (E) => E === 2, C = class C extends g.Component {
constructor(n) {
super(n), this.state = {
activedescendant: w.PopupList,
currentValue: []
}, this._element = null, this._valueItemsDuringOnChange = null, this.base = new O(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: o, virtual: s } = this.props, a = x(this.props), i = s ? s.skip : 0, p = a[e - i], r = this.value.findIndex((h) => P(h, p, o));
this._lastSelectedOrDeslectedItemIndex = a.findIndex((h) => P(h, p, o));
let d = [];
r !== -1 ? (d = this.value, d.splice(r, 1)) : d = [...this.value, p], (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(d, t), this.base.triggerPageChangeCornerItems(p, t);
}, this.onTagDelete = (e, t) => {
const o = this.base.initState();
o.syntheticEvent = t, this.opened && this.base.togglePopup(o), !this.state.focused && !this.mobileMode && (o.data.focused = !0, this.focus());
const s = this.value;
D(s, e, this.props.dataItemKey), this.triggerOnChange(s, o), this.applyState(o);
}, this.itemFocus = (e, t) => {
const { allowCustom: o, virtual: s } = this.props, a = x(this.props), i = s ? s.skip : 0, p = s ? s.pageSize : 0, r = this.props.filter !== void 0 ? this.props.filter : this.state.text, { focusedIndex: d } = this.getFocusedState(), l = o && r, h = a[e - i];
if (s && !h && e >= 0 && d !== e) {
const f = Math.floor(e / p) * p;
if (f !== i) {
this.state.focusedIndex !== e && (t.data.focusedIndex = e, t.data.activedescendant = w.PopupList), this.base.triggerOnPageChange(t, f, p);
return;
}
}
h && d !== e ? this.state.focusedIndex !== e && (t.data.focusedIndex = e, t.data.activedescendant = w.PopupList) : l && e === -1 && this.state.focusedIndex !== void 0 && (t.data.focusedIndex = void 0), this.base.triggerPageChangeCornerItems(h, 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(), o = e.target.value;
t.syntheticEvent = e, this.props.filter === void 0 && (t.data.text = o), t.data.focusedIndex = void 0, this.opened ? this.scrollToFocused = !0 : (this.base.togglePopup(t), this.setState({ currentValue: this.value })), this.base.filterChanged(o, 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 o = this.props.filter !== void 0 ? this.props.filter : this.state.text;
_(o) && o !== "" && this.base.filterChanged("", t), this.state.text && (t.data.text = ""), this._lastSelectedOrDeslectedItemIndex = null, this.applyState(t);
}, this.onInputKeyDown = (e) => {
const { textField: t, groupField: o, virtual: s } = this.props, a = x(this.props), i = e.keyCode, p = this.props.filter !== void 0 ? this.props.filter : this.state.text, r = this.props.opened !== void 0 ? this.props.opened : this.state.opened, { focusedItem: d, focusedIndex: l } = this.getFocusedState(), h = this.base.initState();
if (h.syntheticEvent = e, !p && this.value.length > 0 && (i === u.left || i === u.right || i === u.home || i === u.end || i === u.delete || i === u.backspace) && !e.shiftKey)
return this.onTagsNavigate(e, h);
const f = () => {
e.preventDefault(), this.base.togglePopup(h), this.applyState(h);
};
if (this.opened)
if (i === u.pageUp)
e.preventDefault(), this.base.scrollPopupByPageSize(-1);
else if (i === u.pageDown)
e.preventDefault(), this.base.scrollPopupByPageSize(1);
else if ((e.ctrlKey || e.metaKey) && e.code === "KeyA") {
const b = (this.state.value && this.state.value.length) === a.length ? [] : a;
this.updateStateOnKeyboardNavigation(b, h);
} else if ((e.ctrlKey || e.metaKey) && e.shiftKey && e.keyCode === u.end) {
const c = a.slice(this.getFocusedState().focusedIndex);
this.itemFocus(a.length - 1, h), this.updateStateOnKeyboardNavigation(c, h);
} else if ((e.ctrlKey || e.metaKey) && e.shiftKey && e.keyCode === u.home) {
const c = a.slice(0, this.getFocusedState().focusedIndex + 1);
this.itemFocus(0, h), this.updateStateOnKeyboardNavigation(c, h);
} else if (e.shiftKey && e.keyCode === u.up) {
let c;
const b = this.getLastSelectedOrDeselectedIndex(1, l);
b === null ? c = l !== 0 ? a.slice(l - 1, l) : [a[l]] : b === l ? c = [a[b - 1]] : l >= 0 && (c = b > l ? a.slice(l - 1, b) : a.slice(b - 1, l)), c && c.length > 0 && (l >= 1 && this.itemFocus(l - 1, h), this.updateStateOnKeyboardNavigation(c, h));
} else if (e.shiftKey && e.keyCode === u.down) {
let c;
const b = this.getLastSelectedOrDeselectedIndex(0, l);
b === null ? c = l !== a.length - 1 ? a.slice(l, l + 1) : [a[l]] : b === l ? c = a.slice(l, l + 2) : l >= 0 && (c = b > l ? a.slice(l + 1, b + 1) : a.slice(b, l + 2)), c && c.length >= 1 && (this.itemFocus(l + 1, h), this.updateStateOnKeyboardNavigation(c, h));
} else if (e.altKey && i === u.up)
f();
else if (i === u.up || i === u.down) {
const c = s ? s.skip : 0, b = l - c;
if (o !== "" && t)
if (!this.props.skipDisabledItems && r)
this.onNavigate(h, i);
else {
let m = 0;
if (i === u.down || i === u.right) {
const y = a.slice(b + 1).find((I) => !I.disabled && I[t]);
m = y && a.findIndex((I) => I[t] === y[t]), m && m !== -1 && (m = m + c);
} else if (i === u.up || i === u.left) {
let y;
if (l === -1)
y = a, m = a.findIndex((I) => !I.disabled && I[t]), m !== -1 && (m = m + c);
else {
y = a.slice(0, b);
let I = y.pop();
for (; I && I.disabled; )
I = y.pop();
m = I && a.findIndex((T) => T[t] === I[t]), m && m !== -1 && (m = m + c);
}
}
if (m) {
const y = m - l;
this.onNavigate(h, i, y);
} else
this.onNavigate(h, i);
}
else if (!this.props.skipDisabledItems && r)
this.onNavigate(h, i);
else {
let m = null;
if (i === u.down || i === u.right)
m = a.slice(b + 1).find((y) => !y.disabled);
else if (i === u.up || i === u.left) {
const y = a.slice(0, b);
for (m = y.pop(); m && m.disabled; )
m = y.pop();
}
if (m) {
const y = a.indexOf(m);
if (y !== -1) {
const I = c + y - l;
this.onNavigate(h, i, I);
} else
this.onNavigate(h, i);
} else
this.onNavigate(h, i);
}
this.applyState(h), e.preventDefault();
} else i === u.enter ? (e.preventDefault(), this.props.allowCustom && p && d === null ? this.customItemSelect(e) : d && d.disabled ? f() : this.selectFocusedItem(e)) : i === u.esc && f();
else e.altKey && i === u.down ? f() : i === u.esc && this.clearButtonClick(e);
}, this.listContainerContent = () => {
const { header: e, footer: t, allowCustom: o, size: s, groupStickyHeaderItemRender: a, groupField: i, list: p } = this.props, r = x(this.props), d = this.props.filter !== void 0 ? this.props.filter : this.state.text, { focusedType: l } = this.getFocusedState(), h = o && d && /* @__PURE__ */ g.createElement(
"div",
{
className: S("k-list", {
[`k-list-${M[s] || s}`]: s
}),
key: "customitem",
onClick: this.customItemSelect,
onMouseDown: W
},
/* @__PURE__ */ g.createElement(
"div",
{
className: S("k-list-item k-custom-item", { "k-focus": $(l) }),
style: { fontStyle: "italic" }
},
d,
/* @__PURE__ */ g.createElement(B, { name: "plus", icon: oe, style: { position: "absolute", right: "0.5em" } })
)
);
let { group: f } = this.state;
return f === void 0 && i !== void 0 && (f = K(r[0], i)), /* @__PURE__ */ g.createElement(g.Fragment, null, e && /* @__PURE__ */ g.createElement("div", { className: "k-list-header" }, e), h, /* @__PURE__ */ g.createElement(
"div",
{
className: S("k-list", {
[`k-list-${this.mobileMode ? "lg" : M[s] || s}`]: s,
"k-virtual-list": this.base.vs.enabled
})
},
!p && f && r.length !== 0 && /* @__PURE__ */ g.createElement(de, { group: f, groupMode: "modern", render: a }),
this.renderList()
), this.showLicenseWatermark && /* @__PURE__ */ g.createElement(J, { message: this.licenseMessage }), t && /* @__PURE__ */ g.createElement("div", { className: "k-list-footer" }, t));
}, this.renderListContainer = () => {
const e = this.base, { dir: t } = this.props, o = x(this.props), s = this.base.getPopupSettings(), a = s.width !== void 0 ? s.width : e.popupWidth, i = {
dir: t !== void 0 ? t : e.dirCalculated,
width: a,
popupSettings: {
...s,
popupClass: S(s.popupClass, "k-list-container", "k-multiselect-popup"),
anchor: s.anchor || this.element,
show: this.opened,
onOpen: this.onPopupOpened,
onClose: this.onPopupClosed
},
itemsCount: [o.length, this.value.length]
};
return /* @__PURE__ */ g.createElement(ne, { ...i }, this.listContainerContent());
}, this.renderAdaptiveListContainer = () => {
const { adaptiveTitle: e, adaptiveSubtitle: t, filterable: o, filter: s } = this.props, { windowWidth: a = 0 } = this.state, i = s !== void 0 ? s : this.state.text, p = o ? /* @__PURE__ */ g.createElement(
me,
{
value: i,
ref: (d) => {
this._adaptiveInput = d && d.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: (d) => this.closePopup(d),
windowWidth: a,
mobileFilter: p
};
return /* @__PURE__ */ g.createElement(fe, { ...r }, /* @__PURE__ */ g.createElement(ge, null, /* @__PURE__ */ g.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 o = this.props.filter !== void 0 ? this.props.filter : this.state.text;
_(o) && o !== "" && 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 o = this.props.filter !== void 0 ? this.props.filter : this.state.text;
_(o) && o !== "" && this.base.filterChanged("", t), this.state.text && (t.data.text = ""), this.applyState(t);
}, this.renderList = () => {
const {
textField: e,
listNoDataRender: t,
itemRender: o,
groupHeaderItemRender: s,
dataItemKey: a,
virtual: i = { skip: 0, total: void 0 }
} = this.props, p = x(this.props), r = this.base.vs, { focusedIndex: d } = this.getFocusedState(), l = this.base.getPopupSettings(), h = `translateY(${r.translate}px)`;
return /* @__PURE__ */ g.createElement(
le,
{
id: this.base.listBoxId,
show: this.opened,
data: p.slice(),
focusedIndex: d - i.skip,
value: this.value,
textField: e,
valueField: a,
optionsGuid: this.base.guid,
groupField: this.props.groupField,
groupMode: "modern",
listRef: (f) => {
r.list = this.base.list = f;
},
wrapperStyle: this.mobileMode ? {} : { maxHeight: l.height },
wrapperCssClass: "k-list-content",
listStyle: r.enabled ? { transform: h } : void 0,
key: "listKey",
skip: i.skip,
onClick: this.handleItemClick,
itemRender: o,
groupHeaderItemRender: s,
noDataRender: t,
onMouseDown: W,
onBlur: this.handleBlur,
onScroll: this.onScroll,
wrapperRef: r.scrollerRef,
scroller: this.base.renderScrollElement(),
ariaSetSize: i.total
}
);
}, this.onScroll = (e) => {
const { vs: t, list: o } = this.base;
t.scrollHandler(e);
const { groupField: s } = this.props;
let a = x(this.props);
if (!(!s || !a.length) && s) {
const i = this.itemHeight = this.itemHeight || (t.enabled ? t.itemHeight : o ? o.children[0].offsetHeight : 0), r = e.target.scrollTop - t.skip * i;
a = this.base.getGroupedDataModernMode(a, s);
let d = a[0][s];
for (let l = 1; l < a.length && !(i * l > r); l++)
a[l] && a[l][s] && (d = a[l][s]);
d !== this.state.group && this.setState({
group: d
});
}
}, this.customItemSelect = (e) => {
const t = this.props.filter !== void 0 ? this.props.filter : this.state.text, { textField: o } = this.props;
if (!t)
return;
const s = this.base.initState();
s.syntheticEvent = e;
const a = o ? { [o]: t } : t;
this.state.text !== void 0 && (s.data.text = ""), s.data.focusedIndex = void 0, this.base.filterChanged("", s);
const i = [...this.value, a];
this.triggerOnChange(i, s), this.base.togglePopup(s), this.applyState(s);
}, this.handleWrapperClick = (e) => {
const t = this._input;
!this.opened && t && this.focusElement(t);
const o = this.base.initState();
o.syntheticEvent = e, !this.state.focused && !this.mobileMode && (o.events.push({ type: "onFocus" }), o.data.focused = !0), this.mobileMode && (this.setState({ currentValue: this.tagsToRender }), this.mobileMode && window.setTimeout(() => this._adaptiveInput && this._adaptiveInput.focus(), 300)), this.base.togglePopup(o), this.applyState(o);
}, this.handleItemClick = (e, t) => {
const o = this.base.initState();
o.syntheticEvent = t, this.handleItemSelect(e, o), this.props.autoClose && this.base.togglePopup(o), t.stopPropagation(), this.applyState(o);
}, this.handleBlur = (e) => {
if (!this.state.focused || this._skipFocusEvent)
return;
const t = this.base.initState(), { allowCustom: o, 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" })), !o && !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(A);
}
get _inputId() {
return this.props.id;
}
get document() {
if (V)
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(A, {
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((o) => {
t.push({ text: K(o, e), data: [o] });
}) : 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 : C.defaultProps.required;
}
get validityStyles() {
return this.props.validityStyles !== void 0 ? this.props.validityStyles : C.defaultProps.validityStyles;
}
/** @hidden */
componentDidUpdate(n, e) {
var h;
const { virtual: t, groupField: o = "" } = this.props, s = x(this.props), a = t ? t.skip : 0, i = n.virtual ? n.virtual.total : 0, p = n.opened !== void 0 ? n.opened : e.opened, r = !p && this.opened, d = p && !this.opened, l = this.base.getPopupSettings();
if (this.validate(this.props), this.base.didUpdate(), !l.animate && d && this.onPopupClosed(), t && t.total !== i)
this.base.vs.calcScrollElementHeight(), this.base.vs.reset();
else {
let { focusedItem: f, focusedIndex: c } = this.getFocusedState();
o !== "" && (c = (h = this.base.getGroupedDataModernMode(s, o)) == null ? void 0 : h.indexOf(f)), r && t ? this.base.scrollToVirtualItem(t, c - a) : r && !t ? (s && s.length !== 0 && this.base.resetGroupStickyHeader(s[0][o], this), this.base.scrollToItem(c)) : this.opened && p && f && this.scrollToFocused && this.base.scrollToItem(c - a);
}
this.scrollToFocused = !1, this.setValidity();
}
/** @hidden */
componentDidMount() {
var n;
this.observerResize = V && 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: o } = this.props, s = x(this.props), a = this.props.filter !== void 0 ? this.props.filter : this.state.text, { focusedType: i, focusedIndex: p } = this.getFocusedState(), r = o && a, d = $(i), l = this.base, h = l.vs;
if (this.opened && e === u.up && d)
this.state.focusedIndex !== void 0 && (n.data.focusedIndex = void 0);
else {
const f = l.navigation.navigate({
keyCode: e,
current: p,
max: (h.enabled ? h.total : s.length) - 1,
min: r ? -1 : 0,
skipItems: t || void 0
});
f !== void 0 && (this.itemFocus(f, n), this.scrollToFocused = !0);
}
this.applyState(n);
}
/** @hidden */
render() {
const {
style: n,
className: e,
label: t,
dir: o,
disabled: s,
textField: a,
dataItemKey: i,
virtual: p,
size: r,
rounded: d,
fillMode: l,
loading: h,
filter: f
} = this.props, { text: c, focused: b, focusedTag: m, currentValue: y } = this.state, I = this.base.vs, T = this.props.id || this._inputId;
I.enabled = p !== void 0, p !== void 0 && (I.skip = p.skip, I.total = p.total, I.pageSize = p.pageSize);
const k = this.mobileMode && this.opened ? y : this.tagsToRender;
this.setItems(this.tagsToRender, this._tags);
const R = !this.validityStyles || this.validity.valid, q = !!(f !== void 0 ? f : c) || k && k.length > 0, [G, U] = H(this.props.prefix || g.Fragment), [j, Y] = H(this.props.suffix || g.Fragment), L = /* @__PURE__ */ g.createElement(g.Fragment, null, /* @__PURE__ */ g.createElement(
"div",
{
ref: this.componentRef,
className: S("k-multiselect k-input", e, {
[`k-input-${M[r] || r}`]: r,
[`k-rounded-${ve[d] || d}`]: d,
[`k-input-${l}`]: l,
"k-focus": b && !s,
"k-invalid": !R,
"k-disabled": s,
"k-loading": h,
"k-required": this.required
}),
style: t ? { ...n, width: void 0 } : n,
dir: o,
onFocus: (F) => {
this.mobileMode ? this.handleWrapperClick(F) : this.handleFocus(F);
},
onBlur: this.handleBlur,
onClick: this.handleWrapperClick,
onMouseDown: pe
},
this.props.prefix && /* @__PURE__ */ g.createElement(G, { ...U }),
/* @__PURE__ */ g.createElement("div", { className: S("k-input-values") }, /* @__PURE__ */ g.createElement(
"div",
{
className: S("k-chip-list", { [`k-chip-list-${M[r] || r}`]: r }),
role: "listbox",
id: "tagslist-" + this.base.guid
},
k && k.length > 0 && /* @__PURE__ */ g.createElement(
re,
{
tagRender: this.props.tagRender,
onTagDelete: this.onTagDelete,
data: k,
guid: this.base.guid,
focused: m ? k.find((F) => z(F, m, i)) : void 0,
size: r
}
)
), this.renderSearchBar(T)),
h && /* @__PURE__ */ g.createElement(B, { className: "k-input-loading-icon", name: "loading" }),
this.props.suffix && /* @__PURE__ */ g.createElement(j, { ...Y }),
q && /* @__PURE__ */ g.createElement(ue, { onClick: this.clearButtonClick }),
!this.mobileMode && this.renderListContainer()
), this.mobileMode && this.renderAdaptiveListContainer());
return t ? /* @__PURE__ */ g.createElement(
ae,
{
label: t,
editorId: T,
editorValue: c || K(this.value[0], a),
editorValid: R,
editorDisabled: s,
style: { width: n ? n.width : void 0 },
children: L
}
) : L;
}
renderSearchBar(n) {
const { activedescendant: e, focusedTag: t, currentValue: o } = this.state, { disabled: s, placeholder: a, ariaDescribedBy: i, ariaLabelledBy: p, ariaLabel: r, inputAttributes: d } = this.props, l = !this.mobileMode && (this.props.filter !== void 0 ? this.props.filter : this.state.text) || "", { focusedIndex: h } = this.getFocusedState(), f = this.value.length === 0 && !l ? a : void 0, c = o && o.length > 0 ? void 0 : a, b = e === w.TagsList && t !== void 0 ? `tag-${this.base.guid}-${t.text.replace(/\s+/g, "-")}` : `option-${this.base.guid}-${h}`, m = {
accessKey: this.props.accessKey,
tabIndex: this.props.tabIndex
};
return /* @__PURE__ */ g.createElement(
he,
{
id: n,
size: Math.max((f || "").length, l.length, 1),
placeholder: this.mobileMode && this.opened ? c : f,
value: l,
onChange: this.onChangeHandler,
onKeyDown: this.onInputKeyDown,
ref: this.searchbarRef,
disabled: s,
expanded: this.opened,
owns: this.base.listBoxId,
role: "combobox",
activedescendant: b,
ariaDescribedBy: `tagslist-${this.base.guid}${i ? " " + i : ""}`,
ariaLabelledBy: p,
ariaRequired: this.required,
ariaLabel: r,
inputAttributes: d,
...m
}
);
}
onTagsNavigate(n, e) {
const t = n.keyCode, { focusedTag: o } = this.state, s = this._tags, a = this.props.dataItemKey;
let i = o ? s.findIndex((d) => z(d, o, a)) : -1, p;
const r = i !== -1;
if (t === u.left)
r ? i = Math.max(0, i - 1) : i = s.length - 1, p = s[i];
else if (t === u.right)
i === s.length - 1 ? p = void 0 : r && (i = Math.min(s.length - 1, i + 1), p = s[i]);
else if (t === u.home && !n.shiftKey)
p = s[0];
else if (t === u.end && !n.shiftKey)
p = s[s.length - 1];
else if (t === u.delete) {
if (r) {
const d = this.value;
D(d, s[i].data, a), this.triggerOnChange(d, e);
}
} else if (t === u.backspace) {
const d = this.value;
if (r)
D(d, s[i].data, a), this.triggerOnChange(d, e);
else if (!r && s.length) {
const l = s.pop();
D(d, l.data, a), this.triggerOnChange(d, e);
}
}
p !== o && (e.data.focusedTag = p, 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, o = x(this.props), { focusedIndex: s } = e || this.getFocusedState(), a = t ? t.skip : 0;
o[s - a] !== 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: o,
virtual: s,
textField: a,
focusedItemIndex: i = ce,
skipDisabledItems: p
} = this.props, r = x(this.props), d = s && s.skip || 0;
let l;
if (n !== void 0)
return {
focusedIndex: n,
focusedItem: r[n - d],
focusedType: 1
/* ListItem */
};
const h = this.value;
if (t && e)
return {
focusedItem: null,
focusedIndex: -1,
focusedType: 2
/* CustomItem */
};
if (e)
return l = i(r, e, a), {
focusedItem: r[l],
focusedIndex: l + d,
focusedType: 1
/* ListItem */
};
if (h.length) {
const f = h[h.length - 1];
return l = r.findIndex((c) => P(c, f, o)), r[l] !== void 0 ? {
focusedIndex: l + d,
focusedItem: r[l],
focusedType: 1
/* ListItem */
} : { focusedType: 0, focusedIndex: -1 };
} else if (p && a && !e && d === 0) {
const f = r.findIndex((c) => !c.disabled && c[a]);
return {
focusedIndex: f,
focusedItem: r[f - d],
focusedType: 1
/* ListItem */
};
}
return d === 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;
}
};
C.displayName = "MultiSelect", C.propTypes = {
...O.propTypes,
autoClose: v.bool,
value: v.arrayOf(v.any),
defaultValue: v.arrayOf(v.any),
dataItemKey: v.string,
placeholder: v.string,
tags: v.arrayOf(
v.shape({
text: v.string,
data: v.arrayOf(v.any)
})
),
tagRender: v.func,
id: v.string,
ariaLabelledBy: v.string,
ariaDescribedBy: v.string,
groupField: v.string,
list: v.any,
adaptive: v.bool,
adaptiveTitle: v.string,
adaptiveSubtitle: v.string,
onCancel: v.func,
skipDisabledItems: v.bool,
inputAttributes: v.object
}, C.defaultProps = {
...O.defaultProps,
autoClose: !0,
required: !1,
size: "medium",
rounded: "medium",
fillMode: "solid",
groupMode: "modern",
skipDisabledItems: !0,
prefix: void 0,
suffix: void 0
};
let N = C;
const Ie = Z(), ye = ee(
te(
Ie,
se(N)
)
);
ye.displayName = "KendoReactMultiSelect";
export {
ye as MultiSelect,
Ie as MultiSelectPropsContext,
N as MultiSelectWithoutContext
};