@progress/kendo-react-dropdowns
Version:
React DropDowns offer an interface for users to select different items from a list and more. KendoReact Dropdowns package
722 lines (721 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 c 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 c.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__ */ c.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, u = C(this.props), d = n && n.uComboBox;
let { group: v } = this.state;
return v === void 0 && l !== void 0 && (v = D(u[0], l)), /* @__PURE__ */ c.createElement(
"div",
{
className: S(
k.list({
c: d,
list: a,
size: "large",
tableSize: i,
virtual: o
})
)
},
t && /* @__PURE__ */ c.createElement("div", { className: S(k.listHeader({ c: d })) }, t),
!a && v && u.length !== 0 && /* @__PURE__ */ c.createElement(K, { group: v, groupMode: p, render: r }),
this.renderList(),
e && /* @__PURE__ */ c.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 u = 1; u < l.length && !(a * u > n); u++)
l[u] && l[u][r] && (o = l[u][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((h) => F(h, p, r))
), o = t.keyCode, u = 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 && u)
this.onNavigate(d, o);
else {
let h = 0;
if (o === y.down || o === y.right) {
const g = a.slice(n + 1 < a.length ? n + 1 : n).find((f) => !f.disabled && f[i]);
h = g && a.findIndex((f) => f[i] === g[i]);
} else if (o === y.up || o === y.left) {
let g;
if (n === 0)
g = a, h = a.findIndex((f) => !f.disabled && f[i]);
else {
g = a.slice(0, n);
let f = g.pop();
for (; f && f.disabled; )
f = g.pop();
h = f && a.findIndex((E) => E[i] === f[i]);
}
}
if (h !== void 0) {
const g = h - n;
this.onNavigate(d, o, g);
} else h === void 0 && a.findIndex((g) => g[i] === p[i]) === a.length - 1 && this.onNavigate(d, o);
}
else if (!this.props.skipDisabledItems && u)
this.onNavigate(d, o);
else {
let h = null;
if (o === y.down || o === y.right)
h = a.slice(n + 1).find((g) => !g.disabled);
else if (o === y.up || o === y.left) {
const g = a.slice(0, n);
for (h = g.pop(); h && h.disabled; )
h = g.pop();
}
if (h) {
const g = h.id - n - 1;
this.onNavigate(d, o, g);
} else
this.onNavigate(d, o);
}
this.applyState(d);
}
const v = () => {
t.preventDefault(), this.base.togglePopup(d), this.applyState(d);
}, b = this.getFocusedIndex(), x = b === -1, I = !x && this.getCurrentValueDisabledStatus(i, a, b);
u ? 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 && !x && t.currentTarget.value ? a[b][i] : void 0) ? !e && i && I ? this.clearValueOnEnterOrEsc(t) : I || this.applyValueOnEnter(t.currentTarget.value, d) : this.applyValueOnEnter(t.currentTarget.value, d)) : o === y.esc && (!e && i && I && this.clearValueOnEnterOrEsc(t), this.applyValueOnRejectSuggestions(t.currentTarget.value, d)) : !u && 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 u = !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 b = s.value !== void 0 ? s.value : t.value;
let x = this.hasDuplicates ? this.navigationIndex || 0 : a.findIndex((h) => F(h, d, e));
this.props.groupMode === "modern" && l && d && (x = (v = this.base.getGroupedDataModernMode(a, r)) == null ? void 0 : v.map((h) => h[l]).indexOf(d[l]));
const I = !F(b, d, e);
u && i ? this.base.scrollToVirtualItem(i, x) : u && !i ? (this.onPopupOpened(), a && a.length !== 0 && this.base.resetGroupStickyHeader(a[0][r], this), this.base.scrollToItem(x)) : (this.hasDuplicates || n && o && d && I) && this.base.scrollToItem(x);
}
u && 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: u,
virtual: d,
size: v,
rounded: b,
fillMode: x,
opened: I = this.state.opened,
placeholder: h,
svgIcon: g,
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 || c.Fragment), [Q, X] = U(this.props.suffix || c.Fragment), N = /* @__PURE__ */ c.createElement(c.Fragment, null, /* @__PURE__ */ c.createElement(
"span",
{
className: S(
k.wrapper({
c: T,
size: v,
rounded: b,
fillMode: x,
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__ */ c.createElement(Y, { ...J }),
this.renderSearchBar(V || "", L, h),
$ && !o && /* @__PURE__ */ c.createElement(ft, { onClick: this.clearButtonClick, key: "clearbutton" }),
o && /* @__PURE__ */ c.createElement(
st,
{
className: S(k.loadingIcon({ c: T })),
name: "loading",
key: "loading"
}
),
this.props.suffix && /* @__PURE__ */ c.createElement(Q, { ...X }),
/* @__PURE__ */ c.createElement(
bt,
{
tabIndex: -1,
type: "button",
"aria-label": I ? t : s,
icon: u ? void 0 : "caret-alt-down",
svgIcon: g || xt,
iconClass: u,
size: v,
fillMode: x,
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__ */ c.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 u = this.hasDuplicates && this.duplicates.indexOf(o) !== -1;
if (a = this.getFocusedIndex(u), 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__ */ c.createElement(yt, { ...p }, /* @__PURE__ */ c.createElement(It, null, /* @__PURE__ */ c.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: u
} = this.props, d = C(this.props), v = this.props.opened !== void 0 ? this.props.opened : this.state.opened, b = s.getPopupSettings(), x = b.width !== void 0 ? b.width : s.popupWidth, I = u && u.uComboBox;
let { group: h } = this.state;
return h === void 0 && r !== void 0 && (h = D(d[0], r)), /* @__PURE__ */ c.createElement(
ct,
{
width: x,
popupSettings: {
...b,
anchor: b.anchor || this.element,
show: v,
popupClass: S(
b.popupClass,
k.listContainer({
c: I,
popup: !0
})
)
},
dir: t !== void 0 ? t : this.base.dirCalculated,
itemsCount: [d.length]
},
/* @__PURE__ */ c.createElement(
"div",
{
className: S(
k.list({
c: I,
list: p,
size: a,
tableSize: a,
virtual: n
})
)
},
e && /* @__PURE__ */ c.createElement("div", { className: S(k.listHeader({ c: I })) }, e),
!p && h && d.length !== 0 && /* @__PURE__ */ c.createElement(K, { group: h, groupMode: l, render: o }),
this.renderList(),
i && /* @__PURE__ */ c.createElement(
"div",
{
className: S(
k.listFooter({ c: I }),
this.props.footerClassName
)
},
i
)
),
this.showLicenseWatermark && /* @__PURE__ */ c.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(), u = s.vs, d = a.skip, v = this.props.opened !== void 0 ? this.props.opened : this.state.opened, b = `translateY(${u.translate}px)`, x = v ? this.getFocusedIndex(this.hasDuplicates) : void 0, I = this.props.filter !== void 0 ? this.props.filter : this.state.text, h = D(this.value, t), g = w(I) && I !== h ? null : this.value, f = this.props.list || gt, E = p && p.uComboBox;
return /* @__PURE__ */ c.createElement(
f,
{
id: s.listBoxId,
virtual: !!a,
show: v,
data: n,
focusedIndex: x,
value: g,
textField: t,
valueField: e,
groupField: this.props.groupField,
groupMode: this.props.groupMode,
isMultiColumn: this.props.isMultiColumn,
optionsGuid: s.guid,
hasDuplicates: this.hasDuplicates,
listRef: (O) => {
u.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: u.enabled ? { transform: b } : void 0,
key: "listkey",
skip: d,
onClick: this.handleItemClick,
itemRender: r,
groupHeaderItemRender: l,
noDataRender: i,
onMouseDown: (O) => O.preventDefault(),
onScroll: this.onScroll,
wrapperRef: u.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 },
unstyled: u,
inputAttributes: d
} = this.props, v = C(this.props), b = this.props.opened !== void 0 ? this.props.opened : this.state.opened, x = this.value, I = Math.max(
0,
v.findIndex((h) => F(h, x, n))
);
return this._suggested && !F(this._valueOnDidUpdate, x, n) && (this._suggested = ""), /* @__PURE__ */ c.createElement(
ut,
{
id: t,
readOnly: b && this.mobileMode,
placeholder: e,
tabIndex: i,
title: l,
value: s + this._suggested,
suggestedText: this._suggested,
ref: (h) => {
this._input = h && h.input;
},
onClick: this.onInputClick,
onKeyDown: this.onInputKeyDown,
onChange: this.inputOnChange,
onFocus: this.base.handleFocus,
onBlur: this.handleBlur,
disabled: r,
expanded: b,
owns: this.base.listBoxId,
activedescendant: `option-${this.base.guid}-${I + o.skip}`,
role: "combobox",
ariaLabelledBy: a,
ariaLabel: this.props.ariaLabel,
ariaDescribedBy: p,
ariaRequired: this.required,
render: this.props.valueRender,
ariaControls: this.base.listBoxId,
unstyled: u,
inputAttributes: d
}
);
}
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
};