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

723 lines (722 loc) • 30.7 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 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 };