@progress/kendo-react-data-tools
Version:
Includes React Pager & React Filter component, an intuitive interface to create complex filter descriptions. KendoReact Data Tools package
154 lines (153 loc) • 6.15 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 p from "react";
import u from "prop-types";
import { validatePackage as w, Navigation as b, disableNavigatableContainer as g, getActiveElement as f, focusFirstFocusableChild as h, enableNavigatableContainer as R, classNames as y, WatermarkOverlay as E } from "@progress/kendo-react-common";
import { Group as F } from "./Group.mjs";
import { packageMetadata as k } from "../package-metadata.mjs";
const a = {
// Group selectors
andButton: "button.k-group-start",
orButton: "button.k-group-end",
addFilterButton: 'button[title="Add Expression"]',
addGroupButton: 'button[title="Add Group"]',
removeButton: 'button[title="Remove"]',
// Expression selectors
filterFieldWrapper: ".k-filter-field",
filterOperatorWrapper: ".k-filter-operator",
filterValueWrapper: ".k-filter-value",
toolbarElement: ".k-toolbar"
}, d = class d extends p.Component {
constructor(o) {
super(o), this.wrapperRef = p.createRef(), this.showLicenseWatermark = !1, this.onFilterChange = (r) => {
const t = {
filter: r.nextFilter,
syntheticEvent: r.syntheticEvent,
nativeEvent: r.nativeEvent,
target: this
};
this.props.onChange.call(void 0, t);
}, this.onGroupRemove = (r) => {
const t = {
filter: { ...this.props.value, filters: [] },
syntheticEvent: r.syntheticEvent,
nativeEvent: r.nativeEvent,
target: this
};
this.props.onChange.call(void 0, t);
}, this.onKeyDown = (r) => {
var t;
(t = this.navigation) == null || t.triggerKeyboardEvent(r);
}, this.showLicenseWatermark = !w(k, { component: "Filter" });
}
/**
* @hidden
*/
componentDidMount() {
this.wrapperRef && (this.navigation = new b({
tabIndex: 0,
root: this.wrapperRef,
selectors: [".k-filter"],
keyboardEvents: {
keydown: {
Tab: (o, r, t) => {
const e = o.getElementsByClassName("k-filter-lines")[0];
e && g(e);
},
ArrowUp: (o, r, t) => {
t.preventDefault();
const e = f(document), i = e == null ? void 0 : e.closest(a.toolbarElement), n = o.getElementsByClassName("k-toolbar"), s = Array.from(n).findIndex((m) => m === i) - 1, c = n[s];
o.getElementsByClassName("k-filter-lines")[0] && h(c);
},
ArrowDown: (o, r, t) => {
t.preventDefault();
const e = f(document), i = e == null ? void 0 : e.closest(a.toolbarElement), n = o.getElementsByClassName("k-toolbar"), s = Array.from(n).findIndex((m) => m === i) + 1, c = n[s], l = o.getElementsByClassName("k-filter-lines")[0];
l && (R(l, [
a.filterFieldWrapper,
a.filterOperatorWrapper,
a.filterValueWrapper
]), h(c));
},
ArrowRight: (o, r, t) => {
t.preventDefault();
const e = f(document), i = e == null ? void 0 : e.nextElementSibling, n = e == null ? void 0 : e.closest(a.toolbarElement), s = o.querySelector('[aria-label="Filter toolbar"]');
e && i && !(n === s) && i.focus();
},
ArrowLeft: (o, r, t) => {
t.preventDefault();
const e = f(document), i = e == null ? void 0 : e.previousElementSibling, n = e == null ? void 0 : e.closest(a.toolbarElement), s = o.querySelector('[aria-label="Filter toolbar"]');
e && i && !(n === s) && i.focus();
},
Enter: (o, r, t) => {
t.preventDefault();
const e = f(document), i = o.querySelector(a.removeButton), n = e == null ? void 0 : e.closest(a.toolbarElement), s = o.getElementsByClassName("k-toolbar"), c = Array.from(s).findIndex((l) => l === n) - 1;
if (n === s[0]) {
const l = n.lastElementChild;
l && l.click();
}
if (n !== s[0]) {
const l = s[c].lastElementChild;
e && e.title === i.title && l && (e.click(), l.focus());
}
}
}
}
}));
}
/**
* @hidden
*/
render() {
return /* @__PURE__ */ p.createElement(
"div",
{
className: y("k-filter", this.props.className),
style: this.props.style,
ref: this.wrapperRef,
onKeyDown: this.onKeyDown
},
/* @__PURE__ */ p.createElement("ul", { role: "tree", className: "k-filter-container", "aria-label": this.props.ariaLabel }, /* @__PURE__ */ p.createElement("li", { role: "treeitem", className: "k-filter-group-main" }, /* @__PURE__ */ p.createElement(
F,
{
filter: this.props.value,
fields: this.props.fields,
ariaLabel: this.props.ariaLabelGroup,
ariaLabelExpression: this.props.ariaLabelExpression,
onChange: this.onFilterChange,
onRemove: this.onGroupRemove,
defaultGroupFilter: this.props.defaultGroupFilter || { logic: "and", filters: [] }
}
))),
this.showLicenseWatermark && /* @__PURE__ */ p.createElement(E, null)
);
}
};
d.propTypes = {
className: u.string,
style: u.object,
fields: function(o, r) {
const t = o[r];
if (t === void 0)
return new Error(`Property '${r}' is missing.`);
if (Array.isArray(t)) {
if (Object.keys(t.reduce((e, i) => ({ ...e, [i.name]: 1 }), {})).length !== t.length)
return new Error(`Property '${r}' needs to contain objects with unique 'name' field.`);
} else return new Error(`Property '${r}' needs to be Array<FieldSettings>.`);
return null;
},
ariaLabelGroup: u.string,
ariaLabelExpression: u.string,
value: u.object.isRequired,
onChange: u.func.isRequired
};
let v = d;
export {
v as Filter,
a as selectors
};