UNPKG

@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
/** * @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 };