@progress/kendo-react-grid
Version: 
React Data Grid (Table) provides 100+ ready-to-use data grid features. KendoReact Grid package
131 lines (130 loc) • 5.26 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
 *-------------------------------------------------------------------------------------------
 */
"use client";
import * as t from "react";
import { Popup as V } from "@progress/kendo-react-popup";
import { TABBABLE_ELEMENTS as _, useDocument as H, Navigation as q, classNames as J, IconWrap as D, getActiveElement as Q, Keys as U } from "@progress/kendo-react-common";
import { moreVerticalIcon as X } from "@progress/kendo-svg-icons";
import { columnMenu as b, messages as Y } from "../messages/index.mjs";
import { useLocalization as Z } from "@progress/kendo-react-intl";
import { GridContext as O } from "../utils/GridContext.mjs";
import { GridColumnMenuAdaptiveProvider as j } from "./adaptiveContext/GridColumnMenuAdaptiveContext.mjs";
import { GridAdaptiveColumnMenu as ee } from "./adaptiveContent/GridAdaptiveColumnMenu.mjs";
import ne from "react-dom";
const te = [".k-columnmenu-item-content", ".k-filter-menu-container"].map((r) => _.map((c) => `${r} ${c}`)), oe = [[".k-tabstrip-items"], [".k-columnmenu-item"], ...te], Ee = (r) => {
  var y;
  const c = t.useContext(O), [d, M] = t.useState(!1), s = t.useRef(null), i = t.useRef(null), l = t.useRef(null), h = t.useRef(0), A = H(s), { columnMenu: a, ...C } = r, { column: u, columnMenuIcon: g, navigatable: p } = r, T = Z(), w = u.title || u.field, S = w ? `${w} ` : "", x = "#", K = (n) => {
    const e = Q(document);
    clearTimeout(h.current), h.current = window.setTimeout(() => {
      !c.mobileMode && e && n.relatedTarget !== s.current && i.current && !i.current.contains(e) && m();
    });
  }, N = () => {
    clearTimeout(h.current);
  }, B = (n) => {
    n.preventDefault(), d && r.onCloseMenu && r.onCloseMenu(), M(!d);
  }, m = () => {
    r.onCloseMenu && r.onCloseMenu(), M(!1), !r.navigatable && s.current && s.current.focus();
  }, I = (n) => {
    var e;
    if (n.keyCode === U.tab) {
      const o = n.target, f = o && ((e = o.closest(".k-grid")) == null ? void 0 : e.getElementsByClassName("k-grid-content")[0]);
      f && f.scrollWidth > f.clientWidth && o.scrollIntoView({ inline: "center" });
    }
  }, E = t.useMemo(() => r.show !== void 0 ? r.show : d, [r.show, d]), R = (n) => {
    var e;
    (e = l.current) == null || e.triggerKeyboardEvent(n);
  }, F = (n) => {
    var e;
    (e = l.current) == null || e.triggerMouseEvent(n);
  }, G = (n, e, o) => {
    o.preventDefault(), o.shiftKey ? e.focusPrevious(n) : e.focusNext(n);
  }, P = (n, e, o) => {
    n && (o.preventDefault(), n.click());
  }, $ = (n, e, o) => {
    o.preventDefault(), m();
  }, z = (n, e, o) => {
    e.focusElement(n);
  }, L = (n) => {
    !n.isAnchorClicked && M(!1);
  }, v = t.useCallback(
    (n, e) => {
      const o = [];
      if (!e || typeof e != "object")
        return !1;
      if (Array.isArray(e.filters)) {
        for (const f of e.filters)
          if (v(n, f))
            return !0;
      }
      return "field" in e && typeof e.field == "string" && o.push(e.field), o.includes(n);
    },
    []
  ), k = t.useCallback((n, e) => !e || !Array.isArray(e) ? !1 : e.some((o) => o.field === n), []), W = t.useMemo(() => u.field && (v(u.field, c.filter) || k(u.field, c.group)), [u.field, c.filter, c.group, v, k]);
  return t.useEffect(() => (E && i.current && (l.current = new q({
    tabIndex: 0,
    root: i,
    selectors: oe,
    keyboardEvents: {
      keydown: { Tab: G, Enter: P, Escape: $ }
    },
    mouseEvents: { mousedown: z }
  }), l.current.focusElement(l.current.first, null)), () => {
    l.current && (l.current = null);
  }), [E]), /* @__PURE__ */ t.createElement(t.Fragment, null, /* @__PURE__ */ t.createElement(
    "a",
    {
      className: J("k-grid-header-menu k-grid-column-menu", {
        "k-active": W
      }),
      ref: s,
      onClick: B,
      onKeyDown: I,
      href: x,
      tabIndex: p ? -1 : void 0,
      "aria-label": `${p ? "" : S}${T.toLanguageString(
        b,
        Y[b]
      )}`
    },
    g ? /* @__PURE__ */ t.createElement(D, { name: g.name, icon: g }) : /* @__PURE__ */ t.createElement(D, { name: "more-vertical", icon: X })
  ), /* @__PURE__ */ t.createElement(j, null, c.mobileMode ? /* @__PURE__ */ t.createElement(t.Fragment, null, ne.createPortal(
    /* @__PURE__ */ t.createElement(
      ee,
      {
        computedShow: E,
        ColumnMenu: a,
        closeMenu: m
      },
      a && /* @__PURE__ */ t.createElement(a, { ...C, onCloseMenu: m })
    ),
    (y = A()) == null ? void 0 : y.body
  )) : /* @__PURE__ */ t.createElement(
    V,
    {
      anchor: s.current,
      show: E,
      popupClass: "k-grid-columnmenu-popup",
      onMouseDownOutside: L
    },
    /* @__PURE__ */ t.createElement(
      "div",
      {
        ref: i,
        onBlur: K,
        onFocus: N,
        onMouseDown: F,
        onKeyDown: R,
        className: "k-column-menu k-column-menu-md"
      },
      a && /* @__PURE__ */ t.createElement(a, { ...C, onCloseMenu: m })
    )
  )));
};
export {
  Ee as GridColumnMenuWrapper
};