UNPKG

@cgi-learning-hub/ui

Version:

@cgi-learning-hub/ui is an open-source React component library that implements UI for HUB's features

1,651 lines (1,650 loc) 49.7 kB
import { jsx as P } from "react/jsx-runtime"; import * as x from "react"; import { useState as Ce, useMemo as Pe, useEffect as ye } from "react"; import { a as Re, u as L, s as ae, T as Se, b as Le, d as oe, e as D, f as R, h as Me, i as ve, j as se, k as De, l as Oe, m as ie, n as F, o as de, p as j, q as O, r as Y, t as Ve, v as fe, w as Ae, x as v, y as q, z as me, A as G, B as Fe, D as Ne, E as W, F as je, G as _e, H as K, I as le, J as $e, K as Ue, L as B, M as qe, N as Ke, O as Be, P as ze, Q as re, R as pe, S as Ge, U as We, V as Xe, W as Je, X as Qe } from "../../CustomTreeItem-B9FylIhL.js"; import { TreeContainer as Ye, DEFAULT_CHILDREN_INDENT as Ze } from "./style.es.js"; import { buildItemDataMap as He, findItemPath as et, getItemId as tt } from "./utils.es.js"; import { _ as T } from "../../ButtonBase-6TF6t2SP.js"; import { a as Z } from "../../TransitionGroupContext-DbLioz_6.js"; import { P as g } from "../../index-Sy88PpwE.js"; import { G as nt, F as ot } from "../../identifier-PWESmBq6.js"; import { a as S, u as X } from "../../useEventCallback-Y2KwRxBw.js"; import { w as J } from "../../warning-C8W811fV.js"; import { u as st } from "../../index-DX2Sl0Ig.js"; import { u as Ie } from "../../useSlotProps-DdMuGelR.js"; import { u as it } from "../../useForkRef-u29GSuCu.js"; import { s as lt, c as rt } from "../../DefaultPropsProvider-DqazQPtr.js"; import { T as ct } from "../../Typography-Dy8r_tT2.js"; import { A as ut } from "../../Alert-BhLIlUBu.js"; function at(t) { return nt("MuiRichTreeView", t); } ot("MuiRichTreeView", ["root", "item", "itemContent", "itemGroupTransition", "itemIconContainer", "itemLabel", "itemCheckbox", "itemLabelInput"]); class dt { constructor() { this.maxListeners = 20, this.warnOnce = !1, this.events = {}; } on(e, o, i = {}) { let l = this.events[e]; if (l || (l = { highPriority: /* @__PURE__ */ new Map(), regular: /* @__PURE__ */ new Map() }, this.events[e] = l), i.isFirst ? l.highPriority.set(o, !0) : l.regular.set(o, !0), process.env.NODE_ENV !== "production") { const p = l.highPriority.size + l.regular.size; p > this.maxListeners && !this.warnOnce && (this.warnOnce = !0, console.warn([`Possible EventEmitter memory leak detected. ${p} ${e} listeners added.`].join(` `))); } } removeListener(e, o) { this.events[e] && (this.events[e].regular.delete(o), this.events[e].highPriority.delete(o)); } removeAllListeners() { this.events = {}; } emit(e, ...o) { const i = this.events[e]; if (!i) return; const l = Array.from(i.highPriority.keys()), p = Array.from(i.regular.keys()); for (let d = l.length - 1; d >= 0; d -= 1) { const r = l[d]; i.highPriority.has(r) && r.apply(this, o); } for (let d = 0; d < p.length; d += 1) { const r = p[d]; i.regular.has(r) && r.apply(this, o); } } once(e, o) { const i = this; this.on(e, function l(...p) { i.removeListener(e, l), o.apply(i, p); }); } } const ft = (t) => t.isPropagationStopped !== void 0, he = () => { const [t] = x.useState(() => new dt()), e = x.useCallback((...i) => { const [l, p, d = {}] = i; d.defaultMuiPrevented = !1, !(ft(d) && d.isPropagationStopped()) && t.emit(l, p, d); }, [t]), o = x.useCallback((i, l) => (t.on(i, l), () => { t.removeListener(i, l); }), [t]); return { instance: { $$publishEvent: e, $$subscribeEvent: o } }; }; he.params = {}; const ge = ({ plugins: t }) => { const e = new Set(t); return { instance: { getAvailablePlugins: () => e } }; }; ge.params = {}; const H = ({ params: t, store: e }) => { x.useEffect(() => { e.update((i) => t.id === i.id.providedTreeId && i.id.treeId !== void 0 ? i : T({}, i, { id: T({}, i.id, { treeId: t.id ?? Re() }) })); }, [e, t.id]); const o = L(e, ae); return { getRootProps: () => ({ id: o }) }; }; H.params = { id: !0 }; H.getInitialState = ({ id: t }) => ({ id: { treeId: void 0, providedTreeId: t } }); const mt = [he, ge, H], pt = ["apiRef"], It = (t) => { let { props: { apiRef: e }, plugins: o } = t, i = Z(t.props, pt); const l = x.useMemo(() => { const r = {}; return o.forEach((u) => { Object.assign(r, u.params); }), r; }, [o]), { forwardedProps: p, pluginParams: d } = x.useMemo(() => { const r = {}, u = {}; Object.keys(i).forEach((c) => { const n = i[c]; l[c] ? r[c] = n : u[c] = n; }); const h = o.reduce((c, n) => n.applyDefaultValuesToParams ? n.applyDefaultValuesToParams({ params: c }) : c, r); return { forwardedProps: u, pluginParams: h }; }, [o, i, l]); return { forwardedProps: p, pluginParams: d, apiRef: e }; }, ht = (t) => { const { plugins: e, instance: o, publicAPI: i, store: l, rootRef: p } = t, d = x.useCallback((h) => { let c = null, n = null; const s = [], I = {}; e.forEach((m) => { if (!m.itemPlugin) return; const a = m.itemPlugin({ props: h, rootRef: c, contentRef: n }); a != null && a.rootRef && (c = a.rootRef), a != null && a.contentRef && (n = a.contentRef), a != null && a.propsEnhancers && (s.push(a.propsEnhancers), Object.keys(a.propsEnhancers).forEach((f) => { I[f] = !0; })); }); const E = (m) => (a) => { const f = {}; return s.forEach((w) => { const k = w[m]; k != null && Object.assign(f, k(a)); }), f; }, b = Object.fromEntries(Object.keys(I).map((m) => [m, E(m)])); return { contentRef: n, rootRef: c, propsEnhancers: b }; }, [e]), r = x.useCallback(({ itemId: h, children: c, idAttribute: n }) => { let s = c; for (let I = e.length - 1; I >= 0; I -= 1) { const E = e[I]; E.wrapItem && (s = E.wrapItem({ instance: o, itemId: h, children: s, idAttribute: n })); } return s; }, [e, o]), u = x.useCallback(({ children: h }) => { let c = h; for (let n = e.length - 1; n >= 0; n -= 1) { const s = e[n]; s.wrapRoot && (c = s.wrapRoot({ children: c })); } return c; }, [e]); return x.useMemo(() => ({ runItemPlugins: d, wrapItem: r, wrapRoot: u, instance: o, publicAPI: i, store: l, rootRef: p }), [d, r, u, o, i, l, p]); }; class gt { constructor(e) { this.value = void 0, this.listeners = void 0, this.subscribe = (o) => (this.listeners.add(o), () => { this.listeners.delete(o); }), this.getSnapshot = () => this.value, this.update = (o) => { const i = o(this.value); i !== this.value && (this.value = i, this.listeners.forEach((l) => l(i))); }, this.value = e, this.listeners = /* @__PURE__ */ new Set(); } } function bt(t) { return t.current == null && (t.current = {}), t; } function Et(t) { const e = x.useRef({}); return t ? bt(t) : e; } let ce = 0; const Tt = ({ plugins: t, rootRef: e, props: o }) => { const i = x.useMemo(() => [...mt, ...t], [t]), { pluginParams: l, forwardedProps: p, apiRef: d } = It({ plugins: i, props: o }), u = x.useRef({}).current, h = Et(d), c = x.useRef(null), n = it(c, e), s = x.useRef(null); if (s.current == null) { ce += 1; const a = { cacheKey: { id: ce } }; i.forEach((f) => { f.getInitialState && Object.assign(a, f.getInitialState(l)); }), s.current = new gt(a); } const I = ht({ plugins: i, instance: u, publicAPI: h.current, store: s.current, rootRef: c }), E = [], b = (a) => { const f = a({ instance: u, params: l, rootRef: c, plugins: i, store: s.current }); f.getRootProps && E.push(f.getRootProps), f.publicAPI && Object.assign(h.current, f.publicAPI), f.instance && Object.assign(u, f.instance); }; return i.forEach(b), { getRootProps: (a = {}) => { const f = T({ role: "tree" }, p, a, { ref: n }); return E.forEach((w) => { Object.assign(f, w(a)); }), f; }, rootRef: n, contextValue: I }; }, z = {}; function xt(t) { const { contextValue: e, classes: o = z, slots: i = z, slotProps: l = z, children: p } = t, d = x.useMemo(() => ({ classes: o, slots: { collapseIcon: i.collapseIcon, expandIcon: i.expandIcon, endIcon: i.endIcon }, slotProps: { collapseIcon: l.collapseIcon, expandIcon: l.expandIcon, endIcon: l.endIcon } }), [o, i.collapseIcon, i.expandIcon, i.endIcon, l.collapseIcon, l.expandIcon, l.endIcon]); return /* @__PURE__ */ P(Se.Provider, { value: e, children: /* @__PURE__ */ P(Le.Provider, { value: d, children: e.wrapRoot({ children: p }) }) }); } const _ = (t, e, o) => { t.$$publishEvent(e, o); }, wt = (t, e, o) => { if (t == null) throw new Error(["MUI X: The Tree View component requires all items to have a unique `id` property.", "Alternatively, you can use the `getItemId` prop to specify a custom id for each item.", "An item was provided without id in the `items` prop:", JSON.stringify(e)].join(` `)); if (o[t] != null) throw new Error(["MUI X: The Tree View component requires all items to have a unique `id` property.", "Alternatively, you can use the `getItemId` prop to specify a custom id for each item.", `Two items were provided with the same id in the \`items\` prop: "${t}"`].join(` `)); }, Q = ({ disabledItemsFocusable: t, items: e, isItemDisabled: o, getItemLabel: i, getItemChildren: l, getItemId: p, initialDepth: d = 0, initialParentId: r = null, getChildrenCount: u, ignoreChildren: h = !1 }) => { const c = {}, n = {}, s = { [se]: [] }, I = (b, m, a) => { const f = p ? p(b) : b.id; wt(f, b, c); const w = i ? i(b) : b.label; if (w == null) throw new Error(["MUI X: The Tree View component requires all items to have a `label` property.", "Alternatively, you can use the `getItemLabel` prop to specify a custom label for each item.", "An item was provided without label in the `items` prop:", JSON.stringify(b)].join(` `)); const k = l ? l(b) : b.children; c[f] = { id: f, label: w, parentId: a, idAttribute: void 0, expandable: u ? u(b) > 0 : !!(k != null && k.length), disabled: o ? o(b) : !1, depth: m }, n[f] = b; const C = a ?? se; s[C] || (s[C] = []), s[C].push(f), h || k == null || k.forEach((y) => I(y, m + 1, f)); }; e == null || e.forEach((b) => I(b, d, r)); const E = {}; return Object.keys(s).forEach((b) => { E[b] = Me(s[b]); }), { disabledItemsFocusable: t, itemMetaLookup: c, itemModelLookup: n, itemOrderedChildrenIdsLookup: s, itemChildrenIndexesLookup: E }; }, V = ({ instance: t, params: e, store: o }) => { const i = x.useCallback((a) => oe(o.value, a), [o]), l = x.useCallback((a) => { const f = D(o.value, a); return (f == null ? void 0 : f.parentId) || null; }, [o]), p = S((a) => { o.update((f) => T({}, f, { items: T({}, f.items, { loading: a }) })); }), d = S((a) => { o.update((f) => T({}, f, { items: T({}, f.items, { error: a }) })); }), r = S(({ itemId: a, shouldBeDisabled: f }) => { o.update((w) => { if (!w.items.itemMetaLookup[a]) return w; const k = T({}, w.items.itemMetaLookup); return k[a] = T({}, k[a], { disabled: f ?? !k[a].disabled }), T({}, w, { items: T({}, w.items, { itemMetaLookup: k }) }); }); }), u = x.useCallback(() => { const a = (f) => { const w = oe(o.value, f), k = R(o.value, f); return k.length > 0 ? w.children = k.map(a) : delete w.children, w; }; return R(o.value, null).map(a); }, [o]), h = x.useCallback((a) => R(o.value, a), [o]), c = (a) => { const f = D(o.value, a); if (f == null) return null; const w = ve({ treeId: ae(o.value), itemId: a, id: f.idAttribute }); return document.getElementById(w); }, n = x.useRef(!1), s = x.useCallback(() => { n.current = !0; }, []), I = x.useCallback(() => n.current, []), E = ({ items: a, parentId: f, depth: w, getChildrenCount: k }) => { if (a) { const C = Q({ disabledItemsFocusable: e.disabledItemsFocusable, items: a, isItemDisabled: e.isItemDisabled, getItemId: e.getItemId, getItemLabel: e.getItemLabel, getItemChildren: e.getItemChildren, getChildrenCount: k, initialDepth: w, initialParentId: f, ignoreChildren: !0 }); o.update((y) => { let A; return f ? A = { itemModelLookup: T({}, y.items.itemModelLookup, C.itemModelLookup), itemMetaLookup: T({}, y.items.itemMetaLookup, C.itemMetaLookup), itemOrderedChildrenIdsLookup: T({}, C.itemOrderedChildrenIdsLookup, y.items.itemOrderedChildrenIdsLookup), itemChildrenIndexesLookup: T({}, C.itemChildrenIndexesLookup, y.items.itemChildrenIndexesLookup) } : A = { itemModelLookup: C.itemModelLookup, itemMetaLookup: C.itemMetaLookup, itemOrderedChildrenIdsLookup: C.itemOrderedChildrenIdsLookup, itemChildrenIndexesLookup: C.itemChildrenIndexesLookup }, Object.values(y.items.itemMetaLookup).forEach((M) => { C.itemMetaLookup[M.id] || _(t, "removeItem", { id: M.id }); }), T({}, y, { items: T({}, y.items, A) }); }); } }, b = (a) => { o.update((f) => { if (!a) return T({}, f, { items: T({}, f.items, { itemMetaLookup: {}, itemOrderedChildrenIdsLookup: {}, itemChildrenIndexesLookup: {} }) }); const w = Object.keys(f.items.itemMetaLookup).reduce((y, A) => { const M = f.items.itemMetaLookup[A]; return M.parentId === a ? (_(t, "removeItem", { id: M.id }), y) : T({}, y, { [M.id]: M }); }, {}), k = f.items.itemOrderedChildrenIdsLookup, C = f.items.itemChildrenIndexesLookup; return delete C[a], delete k[a], T({}, f, { items: T({}, f.items, { itemMetaLookup: w, itemOrderedChildrenIdsLookup: k, itemChildrenIndexesLookup: C }) }); }); }; x.useEffect(() => { t.areItemUpdatesPrevented() || o.update((a) => { const f = Q({ disabledItemsFocusable: e.disabledItemsFocusable, items: e.items, isItemDisabled: e.isItemDisabled, getItemId: e.getItemId, getItemLabel: e.getItemLabel, getItemChildren: e.getItemChildren }); return Object.values(a.items.itemMetaLookup).forEach((w) => { f.itemMetaLookup[w.id] || _(t, "removeItem", { id: w.id }); }), T({}, a, { items: T({}, a.items, f) }); }); }, [t, o, e.items, e.disabledItemsFocusable, e.isItemDisabled, e.getItemId, e.getItemLabel, e.getItemChildren]); const m = S((a, f) => { e.onItemClick && e.onItemClick(a, f); }); return { getRootProps: () => ({ style: { "--TreeView-itemChildrenIndentation": typeof e.itemChildrenIndentation == "number" ? `${e.itemChildrenIndentation}px` : e.itemChildrenIndentation } }), publicAPI: { getItem: i, getItemDOMElement: c, getItemTree: u, getItemOrderedChildrenIds: h, setIsItemDisabled: r, getParentId: l }, instance: { getItemDOMElement: c, preventItemUpdates: s, areItemUpdatesPrevented: I, addItems: E, setTreeViewLoading: p, setTreeViewError: d, removeChildren: b, handleItemClick: m } }; }; V.getInitialState = (t) => ({ items: T({}, Q({ disabledItemsFocusable: t.disabledItemsFocusable, items: t.items, isItemDisabled: t.isItemDisabled, getItemId: t.getItemId, getItemLabel: t.getItemLabel, getItemChildren: t.getItemChildren }), { loading: !1, error: null }) }); V.applyDefaultValuesToParams = ({ params: t }) => T({}, t, { disabledItemsFocusable: t.disabledItemsFocusable ?? !1, itemChildrenIndentation: t.itemChildrenIndentation ?? "12px" }); V.wrapRoot = ({ children: t }) => /* @__PURE__ */ P(De.Provider, { value: Oe, children: t }); process.env.NODE_ENV !== "production" && (V.wrapRoot.displayName = "useTreeViewItems.wrapRoot"); V.params = { disabledItemsFocusable: !0, items: !0, isItemDisabled: !0, getItemLabel: !0, getItemChildren: !0, getItemId: !0, onItemClick: !0, itemChildrenIndentation: !0 }; function kt(t) { const { componentName: e, propName: o, controlled: i, defaultValue: l, warningPrefix: p = "MUI X" } = t, [{ initialDefaultValue: d, isControlled: r }] = x.useState({ initialDefaultValue: l, isControlled: i !== void 0 }); r !== (i !== void 0) && J([`${p}: A component is changing the ${r ? "" : "un"}controlled ${o} state of ${e} to be ${r ? "un" : ""}controlled.`, "Elements should not switch from uncontrolled to controlled (or vice versa).", `Decide between using a controlled or uncontrolled ${o} element for the lifetime of the component.`, "The nature of the state is determined during the first render. It's considered controlled if the value is not `undefined`.", "More info: https://fb.me/react-controlled-components"], "error"), JSON.stringify(d) !== JSON.stringify(l) && J([`${p}: A component is changing the default ${o} state of an uncontrolled ${e} after being initialized. To suppress this warning opt to use a controlled ${e}.`], "error"); } const be = process.env.NODE_ENV === "production" ? () => { } : kt, Ee = ({ isItemEditable: t, expansionTrigger: e }) => e || (t ? "iconContainer" : "content"), U = ({ instance: t, store: e, params: o }) => { be({ componentName: "Tree View", propName: "expandedItems", controlled: o.expandedItems, defaultValue: o.defaultExpandedItems }), X(() => { e.update((r) => { const u = Ee({ isItemEditable: o.isItemEditable, expansionTrigger: o.expansionTrigger }); return r.expansion.expansionTrigger === u ? r : T({}, r, { expansion: T({}, r.expansion, { expansionTrigger: u }) }); }); }, [e, o.isItemEditable, o.expansionTrigger]); const i = (r, u) => { var h; o.expandedItems === void 0 && e.update((c) => T({}, c, { expansion: T({}, c.expansion, { expandedItems: u }) })), (h = o.onExpandedItemsChange) == null || h.call(o, r, u); }, l = S(({ itemId: r, event: u, shouldBeExpanded: h }) => { const c = ie(e.value); let n; h ? n = [r].concat(c) : n = c.filter((s) => s !== r), o.onItemExpansionToggle && o.onItemExpansionToggle(u, r, h), i(u, n); }), p = S(({ itemId: r, event: u = null, shouldBeExpanded: h }) => { const c = F(e.value, r), n = h ?? !c; if (c === n) return; const s = { isExpansionPrevented: !1, shouldBeExpanded: n, event: u, itemId: r }; _(t, "beforeItemToggleExpansion", s), !s.isExpansionPrevented && t.applyItemExpansion({ itemId: r, event: u, shouldBeExpanded: n }); }), d = (r, u) => { const h = D(e.value, u); if (h == null) return; const n = R(e.value, h.parentId).filter((I) => de(e.value, I) && !F(e.value, I)), s = ie(e.value).concat(n); n.length > 0 && (o.onItemExpansionToggle && n.forEach((I) => { o.onItemExpansionToggle(r, I, !0); }), i(r, s)); }; return X(() => { const r = o.expandedItems; r !== void 0 && e.update((u) => T({}, u, { expansion: T({}, u.expansion, { expandedItems: r }) })); }, [e, o.expandedItems]), { publicAPI: { setItemExpansion: p }, instance: { setItemExpansion: p, applyItemExpansion: l, expandAllSiblings: d } }; }, Ct = []; U.applyDefaultValuesToParams = ({ params: t }) => T({}, t, { defaultExpandedItems: t.defaultExpandedItems ?? Ct }); U.getInitialState = (t) => ({ expansion: { expandedItems: t.expandedItems === void 0 ? t.defaultExpandedItems : t.expandedItems, expansionTrigger: Ee(t) } }); U.params = { expandedItems: !0, defaultExpandedItems: !0, onExpandedItemsChange: !0, onItemExpansionToggle: !0, expansionTrigger: !0 }; const $ = (t) => { const e = {}; return t.forEach((o) => { e[o] = !0; }), e; }, Te = ({ store: t, oldModel: e, newModel: o }) => { const i = /* @__PURE__ */ new Map(); return o.forEach((l) => { i.set(l, !0); }), { added: o.filter((l) => !O(t.value, l)), removed: e.filter((l) => !i.has(l)) }; }, Pt = ({ store: t, selectionPropagation: e, newModel: o, oldModel: i, additionalItemsToPropagate: l }) => { if (!e.descendants && !e.parents) return o; let p = !1; const d = $(o), r = Te({ store: t, newModel: o, oldModel: i }); return l == null || l.forEach((u) => { d[u] ? r.added.includes(u) || r.added.push(u) : r.removed.includes(u) || r.removed.push(u); }), r.added.forEach((u) => { if (e.descendants) { const h = (c) => { c !== u && (p = !0, d[c] = !0), R(t.value, c).forEach(h); }; h(u); } if (e.parents) { const h = (n) => d[n] ? R(t.value, n).every(h) : !1, c = (n) => { const s = j(t.value, n); if (s == null) return; R(t.value, s).every(h) && (p = !0, d[s] = !0, c(s)); }; c(u); } }), r.removed.forEach((u) => { if (e.parents) { let h = j(t.value, u); for (; h != null; ) d[h] && (p = !0, delete d[h]), h = j(t.value, h); } if (e.descendants) { const h = (c) => { c !== u && (p = !0, delete d[c]), R(t.value, c).forEach(h); }; h(u); } }), p ? Object.keys(d) : o; }, yt = Object.is; function xe(t, e) { if (t === e) return !0; if (!(t instanceof Object) || !(e instanceof Object)) return !1; let o = 0, i = 0; for (const l in t) if (o += 1, !yt(t[l], e[l]) || !(l in e)) return !1; for (const l in e) i += 1; return o === i; } function Rt(t, e) { const o = Ve(t), i = fe(t, e); if (O(t, e)) return { disabled: !i, visible: o, indeterminate: !1, checked: !0 }; if (R(t, e).length === 0) return { disabled: !i, visible: o, indeterminate: !1, checked: !1 }; let p = !1, d = !1; const r = (u) => { u !== e && (O(t, u) ? p = !0 : d = !0), R(t, u).forEach(r); }; return r(e), { disabled: !i, visible: o, indeterminate: p && d, checked: Ae(t).parents ? p && !d : !1 }; } const St = ({ props: t }) => { const { itemId: e } = t, { store: o } = Y(), i = L(o, Rt, e, xe); return { propsEnhancers: { checkbox: ({ externalEventHandlers: l, interactions: p }) => T({ tabIndex: -1, onChange: (r) => { var u; (u = l.onChange) == null || u.call(l, r), !r.defaultMuiPrevented && fe(o.value, e) && p.handleCheckboxSelection(r); } }, i) } }; }, N = ({ store: t, params: e }) => { be({ componentName: "Tree View", propName: "selectedItems", controlled: e.selectedItems, defaultValue: e.defaultSelectedItems }); const o = x.useRef(null), i = x.useRef({}), l = (s, I, E) => { var f; const b = je(t.value); let m; const a = v(t.value); if (a && (e.selectionPropagation.descendants || e.selectionPropagation.parents) ? m = Pt({ store: t, selectionPropagation: e.selectionPropagation, newModel: I, oldModel: b, additionalItemsToPropagate: E }) : m = I, e.onItemSelectionToggle) if (a) { const w = Te({ store: t, newModel: m, oldModel: b }); e.onItemSelectionToggle && (w.added.forEach((k) => { e.onItemSelectionToggle(s, k, !0); }), w.removed.forEach((k) => { e.onItemSelectionToggle(s, k, !1); })); } else e.onItemSelectionToggle && m !== b && (b != null && e.onItemSelectionToggle(s, b, !1), m != null && e.onItemSelectionToggle(s, m, !0)); e.selectedItems === void 0 && t.update((w) => T({}, w, { selection: T({}, w.selection, { selectedItems: m }) })), (f = e.onSelectedItemsChange) == null || f.call(e, s, m); }, p = ({ itemId: s, event: I = null, keepExistingSelection: E = !1, shouldBeSelected: b }) => { if (!W(t.value)) return; let m; const a = v(t.value); if (E) { const f = q(t.value), w = O(t.value, s); w && (b === !1 || b == null) ? m = f.filter((k) => k !== s) : !w && (b === !0 || b == null) ? m = [s].concat(f) : m = f; } else b === !1 || b == null && O(t.value, s) ? m = a ? [] : null : m = a ? [s] : s; l( I, m, // If shouldBeSelected === selectorIsItemSelected(store, itemId), we still want to propagate the select. // This is useful when the element is in an indeterminate state. [s] ), o.current = s, i.current = {}; }, d = (s, [I, E]) => { if (!v(t.value)) return; let m = q(t.value).slice(); Object.keys(i.current).length > 0 && (m = m.filter((k) => !i.current[k])); const a = $(m), f = _e(t.value, I, E), w = f.filter((k) => !a[k]); m = m.concat(w), l(s, m), i.current = $(f); }, r = (s, I) => { if (o.current != null) { const [E, b] = Fe(t.value, I, o.current); d(s, [E, b]); } }, u = (s, I) => { d(s, [G(t.value), I]); }, h = (s, I) => { d(s, [I, me(t.value)]); }, c = (s) => { if (!v(t.value)) return; const E = Ne(t.value); l(s, E), i.current = $(E); }, n = (s, I, E) => { if (!v(t.value)) return; let m = q(t.value).slice(); Object.keys(i.current).length === 0 ? (m.push(E), i.current = { [I]: !0, [E]: !0 }) : (i.current[I] || (i.current = {}), i.current[E] ? (m = m.filter((a) => a !== I), delete i.current[I]) : (m.push(E), i.current[E] = !0)), l(s, m); }; return X(() => { t.update((s) => T({}, s, { selection: { selectedItems: e.selectedItems === void 0 ? s.selection.selectedItems : e.selectedItems, isEnabled: !e.disableSelection, isMultiSelectEnabled: e.multiSelect, isCheckboxSelectionEnabled: e.checkboxSelection, selectionPropagation: { descendants: e.selectionPropagation.descendants, parents: e.selectionPropagation.parents } } })); }, [t, e.selectedItems, e.multiSelect, e.checkboxSelection, e.disableSelection, e.selectionPropagation.descendants, e.selectionPropagation.parents]), { getRootProps: () => ({ "aria-multiselectable": e.multiSelect }), publicAPI: { setItemSelection: p }, instance: { setItemSelection: p, selectAllNavigableItems: c, expandSelectionRange: r, selectRangeFromStartToItem: u, selectRangeFromItemToEnd: h, selectItemFromArrowNavigation: n } }; }; N.itemPlugin = St; const Lt = [], Mt = {}; N.applyDefaultValuesToParams = ({ params: t }) => T({}, t, { disableSelection: t.disableSelection ?? !1, multiSelect: t.multiSelect ?? !1, checkboxSelection: t.checkboxSelection ?? !1, defaultSelectedItems: t.defaultSelectedItems ?? (t.multiSelect ? Lt : null), selectionPropagation: t.selectionPropagation ?? Mt }); N.getInitialState = (t) => ({ selection: { selectedItems: t.selectedItems === void 0 ? t.defaultSelectedItems : t.selectedItems, isEnabled: !t.disableSelection, isMultiSelectEnabled: t.multiSelect, isCheckboxSelectionEnabled: t.checkboxSelection, selectionPropagation: t.selectionPropagation } }); N.params = { disableSelection: !0, multiSelect: !0, checkboxSelection: !0, defaultSelectedItems: !0, selectedItems: !0, onSelectedItemsChange: !0, onItemSelectionToggle: !0, selectionPropagation: !0 }; const ue = 1e3; class vt { constructor(e = ue) { this.timeouts = /* @__PURE__ */ new Map(), this.cleanupTimeout = ue, this.cleanupTimeout = e; } register(e, o, i) { this.timeouts || (this.timeouts = /* @__PURE__ */ new Map()); const l = setTimeout(() => { typeof o == "function" && o(), this.timeouts.delete(i.cleanupToken); }, this.cleanupTimeout); this.timeouts.set(i.cleanupToken, l); } unregister(e) { const o = this.timeouts.get(e.cleanupToken); o && (this.timeouts.delete(e.cleanupToken), clearTimeout(o)); } reset() { this.timeouts && (this.timeouts.forEach((e, o) => { this.unregister({ cleanupToken: o }); }), this.timeouts = void 0); } } class Dt { constructor() { this.registry = new FinalizationRegistry((e) => { typeof e == "function" && e(); }); } register(e, o, i) { this.registry.register(e, o, i); } unregister(e) { this.registry.unregister(e); } // eslint-disable-next-line class-methods-use-this reset() { } } class Ot { } function Vt(t) { let e = 0; return function(i, l, p) { t.registry === null && (t.registry = typeof FinalizationRegistry < "u" ? new Dt() : new vt()); const [d] = x.useState(new Ot()), r = x.useRef(null), u = x.useRef(void 0); u.current = p; const h = x.useRef(null); if (!r.current && u.current) { const c = (n, s) => { var I; s.defaultMuiPrevented || (I = u.current) == null || I.call(u, n, s); }; r.current = i.$$subscribeEvent(l, c), e += 1, h.current = { cleanupToken: e }, t.registry.register( d, // The callback below will be called once this reference stops being retained () => { var n; (n = r.current) == null || n.call(r), r.current = null, h.current = null; }, h.current ); } else !u.current && r.current && (r.current(), r.current = null, h.current && (t.registry.unregister(h.current), h.current = null)); x.useEffect(() => { if (!r.current && u.current) { const c = (n, s) => { var I; s.defaultMuiPrevented || (I = u.current) == null || I.call(u, n, s); }; r.current = i.$$subscribeEvent(l, c); } return h.current && t.registry && (t.registry.unregister(h.current), h.current = null), () => { var c; (c = r.current) == null || c.call(r), r.current = null; }; }, [i, l]); }; } const At = { registry: null }, Ft = Vt(At), ee = ({ instance: t, params: e, store: o }) => { const i = S((c) => { o.update((n) => K(n) === c ? n : T({}, n, { focus: T({}, n.focus, { focusedItemId: c }) })); }), l = (c) => { const n = D(o.value, c); return n && (n.parentId == null || F(o.value, n.parentId)); }, p = (c, n) => { const s = t.getItemDOMElement(n); s && s.focus(), i(n), e.onItemFocus && e.onItemFocus(c, n); }, d = S((c, n) => { l(n) && p(c, n); }), r = S(() => { const c = K(o.value); if (c == null) return; if (D(o.value, c)) { const s = t.getItemDOMElement(c); s && s.blur(); } i(null); }); Ft(t, "removeItem", ({ id: c }) => { const n = K(o.value), s = le(o.value); n === c && s != null && p(null, s); }); const u = (c) => (n) => { var I; if ((I = c.onFocus) == null || I.call(c, n), n.defaultMuiPrevented) return; const s = le(o.value); n.target === n.currentTarget && s != null && p(n, s); }, h = (c) => (n) => { var s; (s = c.onBlur) == null || s.call(c, n), !n.defaultMuiPrevented && i(null); }; return { getRootProps: (c) => ({ onFocus: u(c), onBlur: h(c) }), publicAPI: { focusItem: d }, instance: { focusItem: d, removeFocusedItem: r } }; }; ee.getInitialState = () => ({ focus: { focusedItemId: null } }); ee.params = { onItemFocus: !0 }; function Nt(t) { return !!t && t.length === 1 && !!t.match(/\S/); } const we = ({ instance: t, store: e, params: o }) => { const i = st(), l = x.useRef({}), p = S((n) => { l.current = n(l.current); }), d = L(e, $e); x.useEffect(() => { if (t.areItemUpdatesPrevented()) return; const n = {}, s = (I) => { n[I.id] = I.label.substring(0, 1).toLowerCase(); }; Object.values(d).forEach(s), l.current = n; }, [d, o.getItemId, t]); const r = (n, s) => { const I = s.toLowerCase(), E = (f) => { const w = B(e.value, f); return w === null ? G(e.value) : w; }; let b = null, m = E(n); const a = {}; for (; b == null && !a[m]; ) l.current[m] === I ? b = m : (a[m] = !0, m = E(m)); return b; }, u = (n) => W(e.value) && !re(e.value, n), h = (n) => !re(e.value, n) && de(e.value, n); return { instance: { updateFirstCharMap: p, handleItemKeyDown: async (n, s) => { if (n.defaultMuiPrevented || n.altKey || Ue(n.target, n.currentTarget)) return; const I = n.ctrlKey || n.metaKey, E = n.key, b = v(e.value); switch (!0) { // Select the item when pressing "Space" case (E === " " && u(s)): { n.preventDefault(), b && n.shiftKey ? t.expandSelectionRange(n, s) : t.setItemSelection({ event: n, itemId: s, keepExistingSelection: b, shouldBeSelected: void 0 }); break; } // If the focused item has children, we expand it. // If the focused item has no children, we select it. case E === "Enter": { Ke(t, pe) && Be(e.value, s) && !ze(e.value, s) ? t.setEditedItem(s) : h(s) ? (t.setItemExpansion({ event: n, itemId: s }), n.preventDefault()) : u(s) && (b ? (n.preventDefault(), t.setItemSelection({ event: n, itemId: s, keepExistingSelection: !0 })) : O(e.value, s) || (t.setItemSelection({ event: n, itemId: s }), n.preventDefault())); break; } // Focus the next focusable item case E === "ArrowDown": { const m = B(e.value, s); m && (n.preventDefault(), t.focusItem(n, m), b && n.shiftKey && u(m) && t.selectItemFromArrowNavigation(n, s, m)); break; } // Focuses the previous focusable item case E === "ArrowUp": { const m = qe(e.value, s); m && (n.preventDefault(), t.focusItem(n, m), b && n.shiftKey && u(m) && t.selectItemFromArrowNavigation(n, s, m)); break; } // If the focused item is expanded, we move the focus to its first child // If the focused item is collapsed and has children, we expand it case (E === "ArrowRight" && !i || E === "ArrowLeft" && i): { if (I) return; if (F(e.value, s)) { const m = B(e.value, s); m && (t.focusItem(n, m), n.preventDefault()); } else h(s) && (t.setItemExpansion({ event: n, itemId: s }), n.preventDefault()); break; } // If the focused item is expanded, we collapse it // If the focused item is collapsed and has a parent, we move the focus to this parent case (E === "ArrowLeft" && !i || E === "ArrowRight" && i): { if (I) return; if (h(s) && F(e.value, s)) t.setItemExpansion({ event: n, itemId: s }), n.preventDefault(); else { const m = j(e.value, s); m && (t.focusItem(n, m), n.preventDefault()); } break; } // Focuses the first item in the tree case E === "Home": { u(s) && b && I && n.shiftKey ? t.selectRangeFromStartToItem(n, s) : t.focusItem(n, G(e.value)), n.preventDefault(); break; } // Focuses the last item in the tree case E === "End": { u(s) && b && I && n.shiftKey ? t.selectRangeFromItemToEnd(n, s) : t.focusItem(n, me(e.value)), n.preventDefault(); break; } // Expand all siblings that are at the same level as the focused item case E === "*": { t.expandAllSiblings(n, s), n.preventDefault(); break; } // Multi select behavior when pressing Ctrl + a // Selects all the items case (String.fromCharCode(n.keyCode) === "A" && I && b && W(e.value)): { t.selectAllNavigableItems(n), n.preventDefault(); break; } // Type-ahead // TODO: Support typing multiple characters case (!I && !n.shiftKey && Nt(E)): { const m = r(s, E); m != null && (t.focusItem(n, m), n.preventDefault()); break; } } } } }; }; we.params = {}; const jt = [V, U, N, ee, we, pe], _t = ["ownerState"], te = /* @__PURE__ */ x.createContext(null); process.env.NODE_ENV !== "production" && (te.displayName = "RichTreeViewItemsContext"); const ke = /* @__PURE__ */ x.memo(function({ itemSlot: e, itemSlotProps: o, itemId: i }) { const l = x.useContext(te), { store: p } = Y(), d = L(p, D, i), r = L(p, R, i), u = e ?? Ge, h = Ie({ elementType: u, externalSlotProps: o, additionalProps: { label: d == null ? void 0 : d.label, id: d == null ? void 0 : d.idAttribute, itemId: i }, ownerState: { itemId: i, label: d == null ? void 0 : d.label } }), c = Z(h, _t); return /* @__PURE__ */ P(u, T({}, c, { children: r == null ? void 0 : r.map(l) })); }, xe); process.env.NODE_ENV !== "production" && (ke.displayName = "WrappedTreeItem"); function $t(t) { const { slots: e, slotProps: o } = t, { store: i } = Y(), l = e == null ? void 0 : e.item, p = o == null ? void 0 : o.item, d = L(i, R, null), r = x.useCallback((u) => /* @__PURE__ */ P(ke, { itemSlot: l, itemSlotProps: p, itemId: u }, u), [l, p]); return /* @__PURE__ */ P(te.Provider, { value: r, children: d.map(r) }); } const Ut = ["slots", "slotProps"], qt = We(), Kt = (t) => { const { classes: e } = t; return x.useMemo(() => rt({ root: ["root"], item: ["item"], itemContent: ["itemContent"], itemGroupTransition: ["itemGroupTransition"], itemIconContainer: ["itemIconContainer"], itemLabel: ["itemLabel"], itemLabelInput: ["itemLabelInput"], itemCheckbox: ["itemCheckbox"] // itemDragAndDropOverlay: ['itemDragAndDropOverlay'], => feature not available on this component // itemErrorIcon: ['itemErrorIcon'], => feature not available on this component }, at, e), [e]); }, Bt = lt("ul", { name: "MuiRichTreeView", slot: "Root" })({ padding: 0, margin: 0, listStyle: "none", outline: 0, position: "relative" }), ne = /* @__PURE__ */ x.forwardRef(function(e, o) { const i = qt({ props: e, name: "MuiRichTreeView" }), { slots: l, slotProps: p } = i, d = Z(i, Ut); process.env.NODE_ENV !== "production" && i.children != null && J(["MUI X: The Rich Tree View component does not support JSX children.", "If you want to add items, you need to use the `items` prop.", "Check the documentation for more details: https://mui.com/x/react-tree-view/rich-tree-view/items/."]); const { getRootProps: r, contextValue: u } = Tt({ plugins: jt, rootRef: o, props: d }), h = L(u.store, Xe), c = L(u.store, Je), n = Kt(i), s = (l == null ? void 0 : l.root) ?? Bt, I = Ie({ elementType: s, externalSlotProps: p == null ? void 0 : p.root, className: n.root, getSlotProps: r, ownerState: i }); return h ? /* @__PURE__ */ P(ct, { children: "Loading..." }) : c ? /* @__PURE__ */ P(ut, { severity: "error", children: c.message }) : /* @__PURE__ */ P(xt, { contextValue: u, classes: n, slots: l, slotProps: p, children: /* @__PURE__ */ P(s, T({}, I, { children: /* @__PURE__ */ P($t, { slots: l, slotProps: p }) })) }); }); process.env.NODE_ENV !== "production" && (ne.displayName = "RichTreeView"); process.env.NODE_ENV !== "production" && (ne.propTypes = { // ----------------------------- Warning -------------------------------- // | These PropTypes are generated from the TypeScript type definitions | // | To update them edit the TypeScript types and run "pnpm proptypes" | // ---------------------------------------------------------------------- /** * The ref object that allows Tree View manipulation. Can be instantiated with `useTreeViewApiRef()`. */ apiRef: g.shape({ current: g.shape({ focusItem: g.func.isRequired, getItem: g.func.isRequired, getItemDOMElement: g.func.isRequired, getItemOrderedChildrenIds: g.func.isRequired, getItemTree: g.func.isRequired, getParentId: g.func.isRequired, setEditedItem: g.func.isRequired, setIsItemDisabled: g.func.isRequired, setItemExpansion: g.func.isRequired, setItemSelection: g.func.isRequired, updateItemLabel: g.func.isRequired }) }), /** * If `true`, the Tree View renders a checkbox at the left of its label that allows selecting it. * @default false */ checkboxSelection: g.bool, /** * Override or extend the styles applied to the component. */ classes: g.object, className: g.string, /** * Expanded item ids. * Used when the item's expansion is not controlled. * @default [] */ defaultExpandedItems: g.arrayOf(g.string), /** * Selected item ids. (Uncontrolled) * When `multiSelect` is true this takes an array of strings; when false (default) a string. * @default [] */ defaultSelectedItems: g.any, /** * If `true`, will allow focus on disabled items. * @default false */ disabledItemsFocusable: g.bool, /** * If `true` selection is disabled. * @default false */ disableSelection: g.bool, /** * Expanded item ids. * Used when the item's expansion is controlled. */ expandedItems: g.arrayOf(g.string), /** * The slot that triggers the item's expansion when clicked. * @default 'content' */ expansionTrigger: g.oneOf(["content", "iconContainer"]), /** * Used to determine the children of a given item. * * @template R * @param {R} item The item to check. * @returns {R[]} The children of the item. * @default (item) => item.children */ getItemChildren: g.func, /** * Used to determine the id of a given item. * * @template R * @param {R} item The item to check. * @returns {string} The id of the item. * @default (item) => item.id */ getItemId: g.func, /** * Used to determine the string label for a given item. * * @template R * @param {R} item The item to check. * @returns {string} The label of the item. * @default (item) => item.label */ getItemLabel: g.func, /** * This prop is used to help implement the accessibility logic. * If you don't provide this prop. It falls back to a randomly generated id. */ id: g.string, /** * Used to determine if a given item should be disabled. * @template R * @param {R} item The item to check. * @returns {boolean} `true` if the item should be disabled. */ isItemDisabled: g.func, /** * Determine if a given item can be edited. * @template R * @param {R} item The item to check. * @returns {boolean} `true` if the item can be edited. * @default () => false */ isItemEditable: g.oneOfType([g.func, g.bool]), /** * Horizontal indentation between an item and its children. * Examples: 24, "24px", "2rem", "2em". * @default 12px */ itemChildrenIndentation: g.oneOfType([g.number, g.string]), items: g.array.isRequired, /** * If `true`, `ctrl` and `shift` will trigger multiselect. * @default false */ multiSelect: g.bool, /** * Callback fired when Tree Items are expanded/collapsed. * @param {React.SyntheticEvent} event The DOM event that triggered the change. Can be null when the change is caused by the `publicAPI.setItemExpansion()` method. * @param {array} itemIds The ids of the expanded items. */ onExpandedItemsChange: g.func, /** * Callback fired when the `content` slot of a given Tree Item is clicked. * @param {React.MouseEvent} event The DOM event that triggered the change. * @param {string} itemId The id of the focused item. */ onItemClick: g.func, /** * Callback fired when a Tree Item is expanded or collapsed. * @param {React.SyntheticEvent | null} event The DOM event that triggered the change. Can be null when the change is caused by the `publicAPI.setItemExpansion()` method. * @param {array} itemId The itemId of the modified item. * @param {array} isExpanded `true` if the item has just been expanded, `false` if it has just been collapsed. */ onItemExpansionToggle: g.func, /** * Callback fired when a given Tree Item is focused. * @param {React.SyntheticEvent | null} event The DOM event that triggered the change. **Warning**: This is a generic event not a focus event. * @param {string} itemId The id of the focused item. */ onItemFocus: g.func, /** * Callback fired when the label of an item changes. * @param {TreeViewItemId} itemId The id of the item that was edited. * @param {string} newLabel The new label of the items. */ onItemLabelChange: g.func, /** * Callback fired when a Tree Item is selected or deselected. * @param {React.SyntheticEvent} event The DOM event that triggered the change. Can be null when the change is caused by the `publicAPI.setItemSelection()` method. * @param {array} itemId The itemId of the modified item. * @param {array} isSelected `true` if the item has just been selected, `false` if it has just been deselected. */ onItemSelectionToggle: g.func, /** * Callback fired when Tree Items are selected/deselected. * @param {React.SyntheticEvent} event The DOM event that triggered the change. Can be null when the change is caused by the `publicAPI.setItemSelection()` method. * @param {string[] | string} itemIds The ids of the selected items. * When `multiSelect` is `true`, this is an array of strings; when false (default) a string. */ onSelectedItemsChange: g.func, /** * Selected item ids. (Controlled) * When `multiSelect` is true this takes an array of strings; when false (default) a string. */ selectedItems: g.any, /** * When `selectionPropagation.descendants` is set to `true`. * * - Selecting a parent selects all its descendants automatically. * - Deselecting a parent deselects all its descendants automatically. * * When `selectionPropagation.parents` is set to `true`. * * - Selecting all the descendants of a parent selects the parent automatically. * - Deselecting a descendant of a selected parent deselects the parent automatically. * * Only works when `multiSelect` is `true`. * On the <SimpleTreeView />, only the expanded items are considered (since the collapsed item are not passed to the Tree View component at all) * * @default { parents: false, descendants: false } */ selectionPropagation: g.shape({ descendants: g.bool, parents: g.bool }), /** * The props used for each component slot. * @default {} */ slotProps: g.object, /** * Overridable component slots. * @default {} */ slots: g.object, /** * The system prop that allows defining system overrides as well as additional CSS styles. */ sx: g.oneOfType([g.arrayOf(g.oneOfType([g.func, g.object, g.bool])), g.func, g.object]) }); const un = ({ items: t, selectedItemId: e, handleSelectedItemChange: o, iconColor: i = "primary", hasNoIcons: l = !1, maxHeight: p = 300, defaultExpandedItems: d = [] }) => { const [r, u] = Ce(d), h = Pe(() => He(t), [t]); return ye(() => { if (e) { const n = et(t, e); if (n) { const s = n.slice(0, -1); u((I) => { const E = s.filter( (b) => !I.includes(b) ); return E.length > 0 ? [...I, ...E] : I; }); } } }, [e, t]), /* @__PURE__ */ P(Ye, { maxHeight: p, "data-treeview-root": "true", children: /* @__PURE__ */ P( ne, { items: t, selectedItems: e, expandedItems: r, onExpandedItemsChange: (n, s) => { u(s); }, itemChildrenIndentation: Ze, onSelectedItemsChange: o, getItemId: tt, slots: { item: (n) => { const s = n.itemId ? h[n.itemId] : void 0; return /* @__PURE__ */ P( Qe, { ...n, itemData: s, iconColor: i, hasNoIcons: l } ); } } } ) }); }; export { un as default };