@progress/kendo-react-dropdowns
Version:
React DropDowns offer an interface for users to select different items from a list and more. KendoReact Dropdowns package
723 lines (722 loc) • 30.7 kB
JavaScript
/**
* @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 g from "react";
import m from "prop-types";
import _ from "../common/DropDownBase.mjs";
import { classNames as S, uComboBox as k, Keys as y, validatePackage as tt, svgIconPropType as et, canUseDOM as R, IconWrap as st, WatermarkOverlay as it, createPropsContext as ot, withIdHOC as at, withPropsContext as nt, withUnstyledHOC as lt, withAdaptiveModeContext as rt } from "@progress/kendo-react-common";
import { FloatingLabel as pt } from "@progress/kendo-react-labels";
import { getPlainDataDuplicates as dt, getFilteredData as C, areSame as F, getItemValue as D, isPresent as w, getItemIndexByText as A, suggestValue as ht, itemIndexStartsWith as z } from "../common/utils.mjs";
import ut from "../common/SearchBar.mjs";
import ct from "../common/ListContainer.mjs";
import gt from "../common/List.mjs";
import mt from "../common/ListFilter.mjs";
import K from "../common/GroupStickyHeader.mjs";
import { packageMetadata as vt } from "../package-metadata.mjs";
import ft from "../common/ClearButton.mjs";
import { Button as bt } from "@progress/kendo-react-buttons";
import { caretAltDownIcon as xt } from "@progress/kendo-svg-icons";
import { comboArrowBtnAriaLabelExpand as H, messages as W, comboArrowBtnAriaLabelCollapse as q } from "../messages/index.mjs";
import { provideLocalizationService as G } from "@progress/kendo-react-intl";
import { ActionSheetContent as It } from "@progress/kendo-react-layout";
import U from "../common/withCustomComponent.mjs";
import { AdaptiveMode as yt } from "../common/AdaptiveMode.mjs";
const Ct = "Please enter a valid value!", M = class M extends g.Component {
constructor(s) {
super(s), this.state = {}, this.base = new _(this), this._element = null, this._suggested = "", this._skipBlur = !1, this._input = null, this._adaptiveFilterInput = null, this._skipFocus = !1, this.itemHeight = 0, this.duplicates = [], this.hasDuplicates = !1, this.showLicenseWatermark = !1, this.focus = () => {
this._input && this._input.focus();
}, this.checkForDuplicatePlainTextRecords = () => {
const t = this.props.textField !== void 0, e = this.props.dataItemKey !== void 0;
if (this.props.data && this.props.data.length > 0 && !t && !e) {
const i = this.props.data;
this.duplicates = dt(i), this.hasDuplicates = this.duplicates.length > 0;
}
}, this.handleItemSelect = (t, e) => {
const { virtual: i, dataItemKey: r } = this.props, l = C(this.props), a = i ? i.skip : 0, p = l[t - a], n = this.hasDuplicates || !F(p, this.value, r);
this.triggerOnChange(p, e), this.state.text !== void 0 && (e.data.text = void 0), n && this.base.triggerPageChangeCornerItems(p, e);
}, this.onPopupOpened = () => {
setTimeout(() => {
this.mobileMode && this._adaptiveFilterInput && (this._skipBlur = !0, this._adaptiveFilterInput.focus(), this._skipBlur = !1);
}, 300);
}, this.componentRef = (t) => {
this._element = t, this.base.wrapper = t;
}, this.toggleBtnClick = (t) => {
this._skipFocus = !0;
const { skipDisabledItems: e, textField: i } = this.props, r = C(this.props), l = this.getFocusedIndex(), a = this.getCurrentValueDisabledStatus(i, r, l), p = this.props.opened !== void 0 ? this.props.opened : this.state.opened, n = this.base.initState();
if (n.syntheticEvent = t, !e && i && a && this.clearValueOnToggleBtnClick(t), this.base.togglePopup(n), !p && this.mobileMode) {
const o = this.props.adaptiveFilter !== void 0 ? this.props.adaptiveFilter : this.state.text || null;
this.base.filterChanged(o, n);
}
this.applyState(n), setTimeout(() => {
this._skipFocus = !1;
}, 300);
}, this.closeOpenedApplyStateNonMobileMode = (t, e) => {
e && !this.mobileMode && this.base.togglePopup(t);
}, this.renderMobileListFilter = () => {
const t = this.props.adaptiveFilter !== void 0 ? this.props.adaptiveFilter : this.state.text, e = D(this.value, this.props.textField), i = w(t) ? t : e;
return /* @__PURE__ */ g.createElement(
mt,
{
value: i,
ref: (r) => {
this._adaptiveFilterInput = r && r.element;
},
onChange: this.handleMobileFilterChange,
onKeyDown: this.onInputKeyDown,
size: "large",
rounded: this.props.rounded,
fillMode: this.props.fillMode,
placeholder: this.props.placeholder
}
);
}, this.listContainerContent = () => {
const { header: t, footer: e, size: i, groupStickyHeaderItemRender: r, groupField: l, list: a, groupMode: p, unstyled: n, virtual: o } = this.props, h = C(this.props), d = n && n.uComboBox;
let { group: v } = this.state;
return v === void 0 && l !== void 0 && (v = D(h[0], l)), /* @__PURE__ */ g.createElement(
"div",
{
className: S(
k.list({
c: d,
list: a,
size: "large",
tableSize: i,
virtual: o
})
)
},
t && /* @__PURE__ */ g.createElement("div", { className: S(k.listHeader({ c: d })) }, t),
!a && v && h.length !== 0 && /* @__PURE__ */ g.createElement(K, { group: v, groupMode: p, render: r }),
this.renderList(),
e && /* @__PURE__ */ g.createElement(
"div",
{
className: S(k.listFooter({ c: d }), this.props.footerClassName)
},
e
)
);
}, this.handleMobileFilterChange = (t) => {
const e = this.base.initState();
e.syntheticEvent = t.syntheticEvent, e.data.text = t.target.value, this.base.filterChanged(t.target.value, e), this.applyState(e);
}, this.onScroll = (t) => {
const { vs: e, list: i } = this.base;
e.scrollHandler(t);
const { groupField: r } = this.props;
let l = C(this.props);
if (!r || !l.length)
return;
const a = this.itemHeight = this.itemHeight || (e.enabled ? e.itemHeight : i ? i.children[0].offsetHeight : 0), n = t.target.scrollTop - e.skip * a;
this.props.groupMode === "modern" && (l = this.base.getGroupedDataModernMode(l, r));
let o = l[0][r];
for (let h = 1; h < l.length && !(a * h > n); h++)
l[h] && l[h][r] && (o = l[h][r]);
o !== this.state.group && (this.setState({
group: o
}), this.props.onGroupScroll && this.props.onGroupScroll.call(void 0, { group: o }));
}, this.handleItemClick = (t, e) => {
this.navigationIndex = t, this.base.handleItemClick(t, e), this._valueDuringOnChange = void 0;
}, this.handleBlur = (t) => {
if (this.state.focused && !this._skipBlur) {
const e = this.base.initState(), { textField: i } = this.props, r = C(this.props), l = this.getFocusedIndex(), p = !(l === -1) && this.getCurrentValueDisabledStatus(i, r, l);
e.data.focused = !1, e.events.push({ type: "onBlur" }), e.syntheticEvent = t, i && p && this.clearValueOnBlur(t), this.applyValueOnRejectSuggestions(t.currentTarget.value, e);
}
}, this.onInputClick = (t) => {
const e = this.props.opened !== void 0 ? this.props.opened : this.state.opened, i = this.props.adaptiveFilter !== void 0 ? this.props.adaptiveFilter : this.state.text || null;
if (!e && this.mobileMode) {
const r = this.base.initState();
r.syntheticEvent = t, this.base.togglePopup(r), this.base.filterChanged(i, r), this.applyState(r);
}
}, this.onInputKeyDown = (t) => {
const { skipDisabledItems: e, textField: i, dataItemKey: r, groupField: l } = this.props, a = C(this.props), p = this.value, n = Math.max(
0,
a.findIndex((u) => F(u, p, r))
), o = t.keyCode, h = this.props.opened !== void 0 ? this.props.opened : this.state.opened, d = this.base.initState();
if (d.syntheticEvent = t, !t.altKey && (o === y.up || o === y.down)) {
if (t.preventDefault(), l !== "" && i)
if (!this.props.skipDisabledItems && h)
this.onNavigate(d, o);
else {
let u = 0;
if (o === y.down || o === y.right) {
const c = a.slice(n + 1 < a.length ? n + 1 : n).find((f) => !f.disabled && f[i]);
u = c && a.findIndex((f) => f[i] === c[i]);
} else if (o === y.up || o === y.left) {
let c;
if (n === 0)
c = a, u = a.findIndex((f) => !f.disabled && f[i]);
else {
c = a.slice(0, n);
let f = c.pop();
for (; f && f.disabled; )
f = c.pop();
u = f && a.findIndex((E) => E[i] === f[i]);
}
}
if (u !== void 0) {
const c = u - n;
this.onNavigate(d, o, c);
} else u === void 0 && a.findIndex((c) => c[i] === p[i]) === a.length - 1 && this.onNavigate(d, o);
}
else if (!this.props.skipDisabledItems && h)
this.onNavigate(d, o);
else {
let u = null;
if (o === y.down || o === y.right)
u = a.slice(n + 1).find((c) => !c.disabled);
else if (o === y.up || o === y.left) {
const c = a.slice(0, n);
for (u = c.pop(); u && u.disabled; )
u = c.pop();
}
if (u) {
const c = u.id - n - 1;
this.onNavigate(d, o, c);
} else
this.onNavigate(d, o);
}
this.applyState(d);
}
const v = () => {
t.preventDefault(), this.base.togglePopup(d), this.applyState(d);
}, x = this.getFocusedIndex(), I = x === -1, b = !I && this.getCurrentValueDisabledStatus(i, a, x);
h ? o === y.pageUp ? (t.preventDefault(), this.base.scrollPopupByPageSize(-1)) : o === y.pageDown ? (t.preventDefault(), this.base.scrollPopupByPageSize(1)) : t.altKey && o === y.up ? v() : o === y.enter ? (t.preventDefault(), (i && !I && t.currentTarget.value ? a[x][i] : void 0) ? !e && i && b ? this.clearValueOnEnterOrEsc(t) : b || this.applyValueOnEnter(t.currentTarget.value, d) : this.applyValueOnEnter(t.currentTarget.value, d)) : o === y.esc && (!e && i && b && this.clearValueOnEnterOrEsc(t), this.applyValueOnRejectSuggestions(t.currentTarget.value, d)) : !h && o === y.esc ? this.clearValueOnEnterOrEsc(t) : t.altKey && o === y.down && v();
}, this.inputOnChange = (t) => {
const e = this.base.initState();
e.syntheticEvent = t;
const i = this.props.opened !== void 0 ? this.props.opened : this.state.opened, r = t.currentTarget, l = r.value;
if (this.props.suggest) {
const a = r.selectionEnd === l.length;
let p = this.props.filter !== void 0 ? this.props.filter : this.state.text;
w(p) || (p = D(this.value, this.props.textField) || "");
const n = p && p === l, o = p && p.length > l.length;
n || o || !a ? this._suggested = "" : this.suggestValue(l);
}
this.props.filter === void 0 && (e.data.text = l), this.state.focusedItem !== void 0 && (e.data.focusedItem = void 0), i || this.base.togglePopup(e), this.base.filterChanged(l, e), this.applyState(e), this.setState({ group: void 0 });
}, this.clearButtonClick = (t) => {
const e = this.base.initState();
e.syntheticEvent = t, t.stopPropagation(), this.clearValue();
}, this.clearValueOnEnterOrEsc = (t) => {
const e = this.base.initState();
e.syntheticEvent = t, t.stopPropagation(), this.clearValue();
}, this.clearValueOnBlur = (t) => {
const e = this.base.initState();
e.syntheticEvent = t, t.stopPropagation(), this.clearValue();
}, this.clearValueOnToggleBtnClick = (t) => {
const e = this.base.initState();
e.syntheticEvent = t, t.stopPropagation(), this.clearValue();
}, this.setValidity = () => {
this._input && this._input.setCustomValidity && this._input.setCustomValidity(
this.validity.valid ? "" : this.props.validationMessage || Ct
);
}, this.handleFocus = (t) => {
if (this._skipFocus)
return;
const e = this.base.initState();
e.syntheticEvent = t, this.mobileMode && !this._skipFocus && (this._skipFocus = !0, this.base.togglePopup(e), this.applyState(e), setTimeout(() => {
this._skipFocus = !1;
}, 300)), this.base.handleFocus(t);
}, this.showLicenseWatermark = !tt(vt, { component: "ComboBox" });
}
get _inputId() {
return this.props.id;
}
get document() {
if (R)
return this.element && this.element.ownerDocument || document;
}
/** @hidden */
get element() {
return this._element;
}
/**
* The mobile mode of the ComboBox.
*/
get mobileMode() {
var t;
return !!(this.state.windowWidth && this.props._adaptiveMode && this.state.windowWidth <= ((t = this.props._adaptiveMode) == null ? void 0 : t.medium) && this.props.adaptive);
}
/**
* The value of the ComboBox.
*/
get value() {
if (this._valueDuringOnChange !== void 0)
return this._valueDuringOnChange;
if (this.props.value !== void 0)
return this.props.value;
if (this.state.value !== void 0)
return this.state.value;
if (this.props.defaultValue !== void 0)
return this.props.defaultValue;
}
/**
* The index of the selected item.
*/
get index() {
const { dataItemKey: s } = this.props, t = C(this.props), e = this.value;
return t.findIndex((i) => F(i, e, s));
}
/**
* Gets the `name` property of the ComboBox.
*/
get name() {
return this.props.name;
}
/**
* Represents the validity state into which the component is set.
*/
get validity() {
const s = this.props.validationMessage !== void 0, t = !this.required || this.value !== null && this.value !== "" && this.value !== void 0, e = this.props.valid !== void 0 ? this.props.valid : t;
return {
customError: s,
valid: e,
valueMissing: this.value === null
};
}
get validityStyles() {
return this.props.validityStyles !== void 0 ? this.props.validityStyles : M.defaultProps.validityStyles;
}
/** @hidden */
get required() {
return this.props.required !== void 0 ? this.props.required : M.defaultProps.required;
}
/** @hidden */
componentDidUpdate(s, t) {
var v;
const { dataItemKey: e, virtual: i, groupField: r = "", textField: l } = this.props, a = C(this.props), p = s.virtual ? s.virtual.total : 0, n = this.props.opened !== void 0 ? this.props.opened : this.state.opened, o = s.opened !== void 0 ? s.opened : t.opened;
s.data !== a && this.checkForDuplicatePlainTextRecords();
const h = !o && n, d = this.value;
if (this._valueOnDidUpdate = d, this.base.didUpdate(), i && i.total !== p)
this.base.vs.calcScrollElementHeight(), this.base.vs.reset();
else {
const x = s.value !== void 0 ? s.value : t.value;
let I = this.hasDuplicates ? this.navigationIndex || 0 : a.findIndex((u) => F(u, d, e));
this.props.groupMode === "modern" && l && d && (I = (v = this.base.getGroupedDataModernMode(a, r)) == null ? void 0 : v.map((u) => u[l]).indexOf(d[l]));
const b = !F(x, d, e);
h && i ? this.base.scrollToVirtualItem(i, I) : h && !i ? (this.onPopupOpened(), a && a.length !== 0 && this.base.resetGroupStickyHeader(a[0][r], this), this.base.scrollToItem(I)) : (this.hasDuplicates || n && o && d && b) && this.base.scrollToItem(I);
}
h && this._input && this._input.focus(), this.setValidity();
}
/** @hidden */
componentDidMount() {
var s;
this.observerResize = R && window.ResizeObserver && new window.ResizeObserver(this.calculateMedia.bind(this)), this.base.didMount(), this.setValidity(), (s = this.document) != null && s.body && this.observerResize && this.observerResize.observe(this.document.body), this.checkForDuplicatePlainTextRecords();
}
/** @hidden */
componentWillUnmount() {
var s;
(s = this.document) != null && s.body && this.observerResize && this.observerResize.disconnect();
}
/** @hidden */
render() {
const s = G(this).toLanguageString(
H,
W[H]
), t = G(this).toLanguageString(
q,
W[q]
), {
dir: e,
disabled: i,
clearButton: r = M.defaultProps.clearButton,
label: l,
textField: a,
className: p,
style: n,
loading: o,
iconClassName: h,
virtual: d,
size: v,
rounded: x,
fillMode: I,
opened: b = this.state.opened,
placeholder: u,
svgIcon: c,
unstyled: f
} = this.props, E = !this.validityStyles || this.validity.valid, O = this.props.filter !== void 0 ? this.props.filter : this.state.text, j = D(this.value, a), V = w(O) ? O : j, $ = r && (!!V || w(this.value)), B = this.base.vs, L = this.props.id || this._inputId, T = f && f.uComboBox;
B.enabled = d !== void 0, d !== void 0 && (B.skip = d.skip, B.total = d.total, B.pageSize = d.pageSize);
const [Y, J] = U(this.props.prefix || g.Fragment), [Q, X] = U(this.props.suffix || g.Fragment), N = /* @__PURE__ */ g.createElement(g.Fragment, null, /* @__PURE__ */ g.createElement(
"span",
{
className: S(
k.wrapper({
c: T,
size: v,
rounded: x,
fillMode: I,
disabled: i,
invalid: !E,
loading: o,
required: this.required
}),
p
),
ref: this.componentRef,
style: l ? { ...n, width: void 0 } : n,
dir: e,
onFocus: this.handleFocus
},
this.props.prefix && /* @__PURE__ */ g.createElement(Y, { ...J }),
this.renderSearchBar(V || "", L, u),
$ && !o && /* @__PURE__ */ g.createElement(ft, { onClick: this.clearButtonClick, key: "clearbutton" }),
o && /* @__PURE__ */ g.createElement(
st,
{
className: S(k.loadingIcon({ c: T })),
name: "loading",
key: "loading"
}
),
this.props.suffix && /* @__PURE__ */ g.createElement(Q, { ...X }),
/* @__PURE__ */ g.createElement(
bt,
{
tabIndex: -1,
type: "button",
"aria-label": b ? t : s,
icon: h ? void 0 : "caret-alt-down",
svgIcon: c || xt,
iconClass: h,
size: v,
fillMode: I,
rounded: null,
themeColor: "base",
className: S(k.inputButton({ c: T })),
onClick: this.toggleBtnClick,
onMouseDown: (Z) => Z.preventDefault()
}
),
!this.mobileMode && this.renderListContainer()
), this.mobileMode && this.renderAdaptiveListContainer());
return l ? /* @__PURE__ */ g.createElement(
pt,
{
label: l,
editorId: L,
editorValue: V,
editorValid: E,
editorDisabled: i,
style: { width: n ? n.width : void 0 },
children: N,
unstyled: f
}
) : N;
}
/** @hidden */
onNavigate(s, t, e) {
const { virtual: i = { skip: 0 } } = this.props, r = C(this.props), l = this.props.filter ? this.props.filter : this.state.text;
let a = -1, p;
const n = this.base.vs, o = this.value;
this._suggested = "";
const h = this.hasDuplicates && this.duplicates.indexOf(o) !== -1;
if (a = this.getFocusedIndex(h), a !== -1 && !w(o))
this.handleItemSelect(a, s);
else if (l === "")
this.handleItemSelect(0, s);
else {
const d = i.skip + a;
p = this.base.navigation.navigate({
keyCode: t,
current: d,
max: (n.enabled ? n.total : r.length) - 1,
min: 0,
skipItems: e || void 0
}), p !== void 0 && this.handleItemSelect(p, s);
}
this.navigationIndex = p;
}
getCurrentValueDisabledStatus(s, t, e) {
return s && t && t[e] && t[e].disabled;
}
applyValueOnEnter(s, t) {
const { textField: e, allowCustom: i } = this.props, r = C(this.props), l = this.props.opened !== void 0 ? this.props.opened : this.state.opened, p = D(this.value, e) === s ? this.index : A(r, s, e), n = p !== -1;
let o;
if (this._suggested = "", n)
o = r[p];
else if (i)
o = e !== void 0 ? { [e]: s } : s;
else
return this.selectFocusedItem(s, t);
this.triggerOnChange(o, t), l && this.base.togglePopup(t), this.props.filter === void 0 && this.state.text !== void 0 && (t.data.text = void 0), this.applyState(t);
}
applyValueOnRejectSuggestions(s, t) {
const { textField: e, allowCustom: i } = this.props, r = C(this.props), l = this.props.opened !== void 0 ? this.props.opened : this.state.opened, a = D(this.value, e);
if (this._suggested = "", s === a || s === "" && !w(a))
return this.closeOpenedApplyStateNonMobileMode(t, l), this.applyState(t);
const p = A(r, s, e, !0), n = p !== -1;
let o = null;
n ? o = r[p] : i && (o = s ? e ? { [e]: s } : s : null), this.triggerOnChange(o, t), this.state.text !== void 0 && (t.data.text = void 0, this.base.filterChanged("", t)), this.closeOpenedApplyStateNonMobileMode(t, l), this.applyState(t);
}
selectFocusedItem(s, t) {
const e = this.props.opened !== void 0 ? this.props.opened : this.state.opened, { textField: i, virtual: r = { skip: 0 }, focusedItemIndex: l = z } = this.props, a = C(this.props), p = r.skip, n = s === "" && p === 0 ? 0 : l(a, s, i);
return n !== -1 ? this.handleItemSelect(n + p, t) : (this.triggerOnChange(null, t), this.state.text !== void 0 && (t.data.text = void 0)), e && this.base.togglePopup(t), this.applyState(t);
}
renderAdaptiveListContainer() {
const { windowWidth: s = 0 } = this.state, { groupField: t, adaptiveTitle: e = this.props.label, adaptiveSubtitle: i } = this.props, r = C(this.props), l = this.props.opened !== void 0 ? this.props.opened : this.state.opened;
let { group: a } = this.state;
a === void 0 && t !== void 0 && (a = D(r[0], t));
const p = {
title: e || this.props.label,
subTitle: i,
expand: l,
onClose: (n) => this.toggleBtnClick(n),
windowWidth: s,
mobileFilter: this.renderMobileListFilter()
};
return /* @__PURE__ */ g.createElement(yt, { ...p }, /* @__PURE__ */ g.createElement(It, null, /* @__PURE__ */ g.createElement("div", { className: "k-list-container" }, this.listContainerContent())));
}
renderListContainer() {
const s = this.base, {
dir: t,
header: e,
footer: i,
groupField: r,
groupMode: l,
size: a,
list: p,
virtual: n,
groupStickyHeaderItemRender: o,
unstyled: h
} = this.props, d = C(this.props), v = this.props.opened !== void 0 ? this.props.opened : this.state.opened, x = s.getPopupSettings(), I = x.width !== void 0 ? x.width : s.popupWidth, b = h && h.uComboBox;
let { group: u } = this.state;
return u === void 0 && r !== void 0 && (u = D(d[0], r)), /* @__PURE__ */ g.createElement(
ct,
{
width: I,
popupSettings: {
...x,
anchor: x.anchor || this.element,
show: v,
popupClass: S(
x.popupClass,
k.listContainer({
c: b,
popup: !0
})
)
},
dir: t !== void 0 ? t : this.base.dirCalculated,
itemsCount: [d.length]
},
/* @__PURE__ */ g.createElement(
"div",
{
className: S(
k.list({
c: b,
list: p,
size: a,
tableSize: a,
virtual: n
})
)
},
e && /* @__PURE__ */ g.createElement("div", { className: S(k.listHeader({ c: b })) }, e),
!p && u && d.length !== 0 && /* @__PURE__ */ g.createElement(K, { group: u, groupMode: l, render: o }),
this.renderList(),
i && /* @__PURE__ */ g.createElement(
"div",
{
className: S(
k.listFooter({ c: b }),
this.props.footerClassName
)
},
i
)
),
this.showLicenseWatermark && /* @__PURE__ */ g.createElement(it, null)
);
}
renderList() {
const s = this.base, {
textField: t,
dataItemKey: e,
listNoDataRender: i,
itemRender: r,
groupHeaderItemRender: l,
virtual: a = { skip: 0, total: void 0 },
unstyled: p
} = this.props, n = C(this.props), o = s.getPopupSettings(), h = s.vs, d = a.skip, v = this.props.opened !== void 0 ? this.props.opened : this.state.opened, x = `translateY(${h.translate}px)`, I = v ? this.getFocusedIndex(this.hasDuplicates) : void 0, b = this.props.filter !== void 0 ? this.props.filter : this.state.text, u = D(this.value, t), c = w(b) && b !== u ? null : this.value, f = this.props.list || gt, E = p && p.uComboBox;
return /* @__PURE__ */ g.createElement(
f,
{
id: s.listBoxId,
virtual: !!a,
show: v,
data: n,
focusedIndex: I,
value: c,
textField: t,
valueField: e,
groupField: this.props.groupField,
groupMode: this.props.groupMode,
isMultiColumn: this.props.isMultiColumn,
optionsGuid: s.guid,
hasDuplicates: this.hasDuplicates,
listRef: (O) => {
h.list = this.base.list = O, this.itemHeight = 0;
},
wrapperStyle: this.state.windowWidth && this.props._adaptiveMode && this.state.windowWidth > this.props._adaptiveMode.medium ? { maxHeight: o.height } : {},
wrapperCssClass: S(
k.listContent({
c: E,
virtual: a
})
),
listStyle: h.enabled ? { transform: x } : void 0,
key: "listkey",
skip: d,
onClick: this.handleItemClick,
itemRender: r,
groupHeaderItemRender: l,
noDataRender: i,
onMouseDown: (O) => O.preventDefault(),
onScroll: this.onScroll,
wrapperRef: h.scrollerRef,
scroller: this.base.renderScrollElement(),
ariaSetSize: a.total
}
);
}
renderSearchBar(s, t, e) {
const {
tabIndex: i,
disabled: r,
title: l,
ariaLabelledBy: a,
ariaDescribedBy: p,
dataItemKey: n,
virtual: o = { skip: 0 },
accessKey: h,
unstyled: d,
inputAttributes: v
} = this.props, x = C(this.props), I = this.props.opened !== void 0 ? this.props.opened : this.state.opened, b = this.value, u = Math.max(
0,
x.findIndex((c) => F(c, b, n))
);
return this._suggested && !F(this._valueOnDidUpdate, b, n) && (this._suggested = ""), /* @__PURE__ */ g.createElement(
ut,
{
id: t,
readOnly: I && this.mobileMode,
placeholder: e,
tabIndex: i,
title: l,
value: s + this._suggested,
suggestedText: this._suggested,
ref: (c) => {
this._input = c && c.input;
},
onClick: this.onInputClick,
onKeyDown: this.onInputKeyDown,
onChange: this.inputOnChange,
onFocus: this.base.handleFocus,
onBlur: this.handleBlur,
disabled: r,
expanded: I,
owns: this.base.listBoxId,
activedescendant: `option-${this.base.guid}-${u + o.skip}`,
role: "combobox",
ariaLabelledBy: a,
ariaLabel: this.props.ariaLabel,
ariaDescribedBy: p,
ariaRequired: this.required,
render: this.props.valueRender,
ariaControls: this.base.listBoxId,
unstyled: d,
inputAttributes: v
}
);
}
clearValue() {
const s = this.base.initState();
this._suggested = "", this.navigationIndex = void 0, this.base.filterChanged("", s), this.props.filter === void 0 && this.state.text !== void 0 && (s.data.text = void 0), this.triggerOnChange(null, s);
const t = this.props.opened !== void 0 ? this.props.opened : this.state.opened, e = this.mobileMode;
t && !e && this.base.togglePopup(s), this.applyState(s);
}
triggerOnChange(s, t) {
const e = this.value;
!this.hasDuplicates && (!w(e) && !w(s) || F(e, s, this.props.dataItemKey)) || (this.props.value === void 0 && (t.data.value = s), this._valueDuringOnChange = s, t.events.push({ type: "onChange" }));
}
getFocusedIndex(s) {
const t = this.value, {
textField: e,
dataItemKey: i,
virtual: r = { skip: 0 },
focusedItemIndex: l = z,
skipDisabledItems: a
} = this.props, p = C(this.props), n = this.props.filter ? this.props.filter : this.state.text;
return s && this.navigationIndex !== void 0 ? this.navigationIndex : w(t) && n === void 0 ? p.findIndex((o) => F(o, t, i)) : n ? l(p, n, e) : a && e && !n && r.skip === 0 ? p.findIndex((o) => !o.disabled && o[e]) : r.skip === 0 ? 0 : -1;
}
suggestValue(s) {
const { data: t, textField: e } = this.props;
this._suggested = ht(s, t, e);
}
applyState(s) {
this.base.applyState(s), this._valueDuringOnChange = void 0;
}
calculateMedia(s) {
for (const t of s)
this.setState({ windowWidth: t.target.clientWidth });
}
};
M.displayName = "ComboBox", M.propTypes = {
..._.propTypes,
size: m.oneOf([null, "small", "medium", "large"]),
rounded: m.oneOf([null, "small", "medium", "large", "full"]),
fillMode: m.oneOf([null, "solid", "flat", "outline"]),
dataItemKey: m.string,
groupField: m.string,
groupMode: m.oneOf([void 0, "classic", "modern"]),
isMultiColumn: m.bool,
suggest: m.bool,
placeholder: m.string,
title: m.string,
allowCustom: m.bool,
clearButton: m.bool,
iconClassName: m.string,
svgIcon: et,
validationMessage: m.string,
required: m.bool,
id: m.string,
ariaLabelledBy: m.string,
ariaLabel: m.string,
ariaDescribedBy: m.string,
list: m.any,
valueRender: m.func,
skipDisabledItems: m.bool,
inputAttributes: m.object
}, M.defaultProps = {
..._.defaultProps,
size: "medium",
rounded: "medium",
fillMode: "solid",
allowCustom: !1,
clearButton: !0,
required: !1,
groupMode: "modern",
isMultiColumn: !1,
skipDisabledItems: !0,
prefix: void 0,
suffix: void 0
};
let P = M;
const St = ot(), kt = at(
nt(
St,
lt(
rt(P)
)
)
);
kt.displayName = "KendoReactComboBox";
export {
kt as ComboBox,
St as ComboBoxPropsContext,
P as ComboBoxWithoutContext
};