@progress/kendo-react-listbox
Version:
React ListBox enables you to display a list of items and manage the data between multiple lists. KendoReact ListBox package
210 lines (209 loc) • 6.87 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 a from "react";
import f from "prop-types";
import { kendoThemeMaps as V, Navigation as j, dispatchEvent as s, classNames as k } from "@progress/kendo-react-common";
import { toolbarPosition as O } from "./interfaces/Enums.mjs";
const R = a.forwardRef((n, T) => {
const {
id: D,
style: F,
data: c,
textField: b,
className: L,
valueField: C,
selectedField: K,
onDrop: z,
onKeyDown: x,
onDragStart: S,
onDragLeave: N,
onDragOver: v,
onItemClick: A,
onItemSelect: d,
onKeyboardNavigate: m,
size: u = g.size,
draggable: $ = g.draggable,
toolbarPosition: p = g.toolbarPosition
} = n, E = a.useRef(null), h = a.useRef(null), w = a.useRef(null), o = a.useCallback(
() => ({
element: w.current,
props: n
}),
[]
);
a.useImperativeHandle(h, o), a.useImperativeHandle(T, () => h.current);
const I = D + "-accessibility-id", P = V.sizeMap[u] || u, B = (t) => {
if (K)
return !!t[K];
}, H = (t) => b ? t[b] : t.toString(), _ = (t) => {
x && s(x, t, o(), void 0);
}, M = (t) => {
t.target.classList.contains("k-list-content") && (n.data.length > 0 ? s(n.onDrop, t, o(), {
dataItem: n.data[n.data.length - 1]
}) : s(n.onDrop, t, o(), {
dataItem: null
}));
}, q = () => p === O.NONE || n.toolbar === void 0 ? `k-listbox-actions-${g.toolbarPosition}` : `k-listbox-actions-${p}`, G = (t) => {
N && t.target.classList.contains("k-list-content") && s(N, t, o(), void 0);
}, y = a.useMemo(
() => new j({
root: E,
selectors: [".k-list-item"],
tabIndex: 0,
keyboardEvents: {
keydown: {
Space: (t, i, e) => {
const r = i.elements.indexOf(t);
e.metaKey && s(d, e, o(), {
dataItem: c[r]
}), s(d, e, o(), { dataItem: c[r] });
},
ArrowDown: (t, i, e) => {
if (e.metaKey && e.shiftKey)
s(m, e, o(), {
actionName: "moveDown"
});
else if (e.metaKey && !e.shiftKey)
e.preventDefault(), i.focusNext(t);
else if (!(e.shiftKey && !e.metaKey)) {
e.preventDefault();
const r = i.elements.indexOf(t), l = c[r + 1];
l && (s(d, e, o(), { dataItem: l }), i.focusNext(t));
}
},
ArrowUp: (t, i, e) => {
if (e.metaKey && e.shiftKey)
s(m, e, o(), {
actionName: "moveUp"
});
else if (e.metaKey && !e.shiftKey)
e.preventDefault(), i.focusPrevious(t);
else if (!(e.shiftKey && !e.metaKey)) {
e.preventDefault();
const r = i.elements.indexOf(t), l = c[r - 1];
l && (s(d, e, o(), { dataItem: l }), i.focusPrevious(t));
}
},
ArrowLeft: (t, i, e) => {
e.metaKey && e.shiftKey ? s(m, e, o(), {
actionName: "transferAllFrom"
}) : e.metaKey && s(m, e, o(), {
actionName: "transferFrom"
});
},
ArrowRight: (t, i, e) => {
e.metaKey && e.shiftKey ? s(m, e, o(), {
actionName: "transferAllTo"
}) : e.metaKey && s(m, e, o(), {
actionName: "transferTo"
});
},
Backspace: (t, i, e) => {
s(m, e, o(), { actionName: "remove" });
}
}
}
}),
[c]
), U = a.useCallback(y.triggerKeyboardEvent.bind(y), [c]);
return a.useEffect(() => (y.initializeRovingTab(), () => y.removeFocusListener()), [c]), /* @__PURE__ */ a.createElement(
"div",
{
id: D,
ref: w,
style: F,
unselectable: "on",
className: k(
L,
"k-listbox",
{ [`k-listbox-${P}`]: u },
q()
)
},
n.toolbar && /* @__PURE__ */ a.createElement(n.toolbar, null),
/* @__PURE__ */ a.createElement(
"div",
{
className: "k-list-scroller k-selectable",
"data-role": "selectable",
ref: E,
onDragOver: (t) => t.preventDefault(),
onDrop: M,
onDragLeave: G,
onKeyDown: U
},
/* @__PURE__ */ a.createElement("div", { className: k("k-list", { [`k-list-${P}`]: u }) }, /* @__PURE__ */ a.createElement("div", { className: "k-list-content" }, /* @__PURE__ */ a.createElement(
"ul",
{
className: "k-list-ul",
role: "listbox",
"aria-label": "listbox-container",
onKeyDown: _
},
c.map((t, i) => {
const e = B(t), r = {
className: k("k-list-item", { "k-selected": e }),
role: "option",
key: i,
id: I + i,
"aria-selected": e,
"data-uid": I + i,
draggable: $,
onDragStart: (l) => {
s(
S,
l,
o(),
{ dataItem: t }
);
},
onDragOver: (l) => {
l.preventDefault(), s(v, l, o(), { dataItem: t });
},
onDrop: (l) => {
s(z, l, o(), { dataItem: t });
},
onClick: (l) => {
s(A, l, o(), { dataItem: t });
}
};
return n.item ? /* @__PURE__ */ a.createElement(
n.item,
{
selected: e,
dataItem: t,
...r,
key: r.key
},
/* @__PURE__ */ a.createElement("span", { className: "k-list-item-text" }, t.name)
) : /* @__PURE__ */ a.createElement("li", { ...r, key: r.key }, /* @__PURE__ */ a.createElement("span", { className: "k-list-item-text" }, H(t)));
})
)))
),
/* @__PURE__ */ a.createElement("select", { style: { display: "none" }, multiple: !0, "data-role": "listbox" }, c.map((t, i) => {
const e = t[C || b];
return /* @__PURE__ */ a.createElement("option", { key: i, value: e }, e);
}))
);
}), g = {
toolbarPosition: O.RIGHT,
draggable: !0,
size: "medium"
};
R.propTypes = {
size: f.oneOf([null, "small", "medium", "large"]),
toolbarPosition: f.oneOf(["none", "top", "bottom", "left", "right"]),
textField: f.string.isRequired,
valueField: f.string,
selectedField: f.string,
data: f.array.isRequired
};
R.displayName = "ListBoxInner";
export {
R as ListBox
};