var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: !0, configurable: !0, writable: !0, value }) : obj[key] = value;
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key != "symbol" ? key + "" : key, value);
// src/slick.core.ts
var SlickEventData = class {
constructor(event2, args) {
this.event = event2;
this.args = args;
__publicField(this, "_isPropagationStopped", !1);
__publicField(this, "_isImmediatePropagationStopped", !1);
__publicField(this, "_isDefaultPrevented", !1);
__publicField(this, "returnValues", []);
__publicField(this, "returnValue");
__publicField(this, "_eventTarget");
__publicField(this, "nativeEvent");
__publicField(this, "arguments_");
// public props that can be optionally pulled from the provided Event in constructor
// they are all optional props because it really depends on the type of Event provided (KeyboardEvent, MouseEvent, ...)
__publicField(this, "altKey");
__publicField(this, "ctrlKey");
__publicField(this, "metaKey");
__publicField(this, "shiftKey");
__publicField(this, "key");
__publicField(this, "keyCode");
__publicField(this, "clientX");
__publicField(this, "clientY");
__publicField(this, "offsetX");
__publicField(this, "offsetY");
__publicField(this, "pageX");
__publicField(this, "pageY");
__publicField(this, "bubbles");
__publicField(this, "target");
__publicField(this, "type");
__publicField(this, "which");
__publicField(this, "x");
__publicField(this, "y");
this.nativeEvent = event2, this.arguments_ = args, event2 && [
"altKey",
"ctrlKey",
"metaKey",
"shiftKey",
"key",
"keyCode",
"clientX",
"clientY",
"offsetX",
"offsetY",
"pageX",
"pageY",
"bubbles",
"target",
"type",
"which",
"x",
"y"
].forEach((key) => this[key] = event2[key]), this._eventTarget = this.nativeEvent ? this.nativeEvent.target : void 0;
}
get defaultPrevented() {
return this._isDefaultPrevented;
}
/**
* Stops event from propagating up the DOM tree.
* @method stopPropagation
*/
stopPropagation() {
this._isPropagationStopped = !0, this.nativeEvent?.stopPropagation();
}
/**
* Returns whether stopPropagation was called on this event object.
* @method isPropagationStopped
* @return {Boolean}
*/
isPropagationStopped() {
return this._isPropagationStopped;
}
/**
* Prevents the rest of the handlers from being executed.
* @method stopImmediatePropagation
*/
stopImmediatePropagation() {
this._isImmediatePropagationStopped = !0, this.nativeEvent && this.nativeEvent.stopImmediatePropagation();
}
/**
* Returns whether stopImmediatePropagation was called on this event object.\
* @method isImmediatePropagationStopped
* @return {Boolean}
*/
isImmediatePropagationStopped() {
return this._isImmediatePropagationStopped;
}
getNativeEvent() {
return this.nativeEvent;
}
preventDefault() {
this.nativeEvent && this.nativeEvent.preventDefault(), this._isDefaultPrevented = !0;
}
isDefaultPrevented() {
return this.nativeEvent ? this.nativeEvent.defaultPrevented : this._isDefaultPrevented;
}
addReturnValue(value) {
this.returnValues.push(value), this.returnValue === void 0 && value !== void 0 && (this.returnValue = value);
}
getReturnValue() {
return this.returnValue;
}
getArguments() {
return this.arguments_;
}
}, SlickEvent = class {
/**
* Constructor
* @param {String} [eventName] - event name that could be used for dispatching CustomEvent (when enabled)
* @param {BasePubSub} [pubSubService] - event name that could be used for dispatching CustomEvent (when enabled)
*/
constructor(eventName, pubSub) {
this.eventName = eventName;
this.pubSub = pubSub;
__publicField(this, "_handlers", []);
__publicField(this, "_pubSubService");
this._pubSubService = pubSub;
}
get subscriberCount() {
return this._handlers.length;
}
/**
* Adds an event handler to be called when the event is fired.
*
Event handler will receive two arguments - an EventData and the data
* object the event was fired with.
* @method subscribe
* @param {Function} fn - Event handler.
*/
subscribe(fn) {
this._handlers.push(fn);
}
/**
* Removes an event handler added with subscribe(fn).
* @method unsubscribe
* @param {Function} [fn] - Event handler to be removed.
*/
unsubscribe(fn) {
for (let i = this._handlers.length - 1; i >= 0; i--)
this._handlers[i] === fn && this._handlers.splice(i, 1);
}
/**
* Fires an event notifying all subscribers.
* @method notify
* @param {Object} args Additional data object to be passed to all handlers.
* @param {EventData} [event] - An EventData object to be passed to all handlers.
* For DOM events, an existing W3C event object can be passed in.
* @param {Object} [scope] - The scope ("this") within which the handler will be executed.
* If not specified, the scope will be set to the Event instance.
*/
notify(args, evt, scope) {
let sed = evt instanceof SlickEventData ? evt : new SlickEventData(evt, args);
scope = scope || this;
for (let i = 0; i < this._handlers.length && !(sed.isPropagationStopped() || sed.isImmediatePropagationStopped()); i++) {
let returnValue = this._handlers[i].call(scope, sed, args);
sed.addReturnValue(returnValue);
}
if (typeof this._pubSubService?.publish == "function" && this.eventName) {
let ret = this._pubSubService.publish(this.eventName, { args, eventData: sed });
sed.addReturnValue(ret);
}
return sed;
}
setPubSubService(pubSub) {
this._pubSubService = pubSub;
}
}, SlickEventHandler = class {
constructor() {
__publicField(this, "handlers", []);
}
subscribe(event2, handler) {
return this.handlers.push({ event: event2, handler }), event2.subscribe(handler), this;
}
unsubscribe(event2, handler) {
let i = this.handlers.length;
for (; i--; )
if (this.handlers[i].event === event2 && this.handlers[i].handler === handler) {
this.handlers.splice(i, 1), event2.unsubscribe(handler);
return;
}
return this;
}
unsubscribeAll() {
let i = this.handlers.length;
for (; i--; )
this.handlers[i].event.unsubscribe(this.handlers[i].handler);
return this.handlers = [], this;
}
}, SlickRange = class {
constructor(fromRow, fromCell, toRow, toCell) {
__publicField(this, "fromRow");
__publicField(this, "fromCell");
__publicField(this, "toCell");
__publicField(this, "toRow");
toRow === void 0 && toCell === void 0 && (toRow = fromRow, toCell = fromCell), this.fromRow = Math.min(fromRow, toRow), this.fromCell = Math.min(fromCell, toCell), this.toCell = Math.max(fromCell, toCell), this.toRow = Math.max(fromRow, toRow);
}
/**
* Returns whether a range represents a single row.
* @method isSingleRow
* @return {Boolean}
*/
isSingleRow() {
return this.fromRow === this.toRow;
}
/**
* Returns whether a range represents a single cell.
* @method isSingleCell
* @return {Boolean}
*/
isSingleCell() {
return this.fromRow === this.toRow && this.fromCell === this.toCell;
}
/**
* Returns whether a range contains a given cell.
* @method contains
* @param row {Integer}
* @param cell {Integer}
* @return {Boolean}
*/
contains(row, cell) {
return row >= this.fromRow && row <= this.toRow && cell >= this.fromCell && cell <= this.toCell;
}
/**
* Returns a readable representation of a range.
* @method toString
* @return {String}
*/
toString() {
return this.isSingleCell() ? `(${this.fromRow}:${this.fromCell})` : `(${this.fromRow}:${this.fromCell} - ${this.toRow}:${this.toCell})`;
}
}, SlickNonDataItem = class {
constructor() {
__publicField(this, "__nonDataRow", !0);
}
}, SlickGroup = class extends SlickNonDataItem {
constructor() {
super();
__publicField(this, "__group", !0);
/**
* Grouping level, starting with 0.
* @property level
* @type {Number}
*/
__publicField(this, "level", 0);
/**
* Number of rows in the group.
* @property count
* @type {Integer}
*/
__publicField(this, "count", 0);
/**
* Grouping value.
* @property value
* @type {Object}
*/
__publicField(this, "value", null);
/**
* Formatted display value of the group.
* @property title
* @type {String}
*/
__publicField(this, "title", null);
/**
* Whether a group is collapsed.
* @property collapsed
* @type {Boolean}
*/
__publicField(this, "collapsed", !1);
/**
* Whether a group selection checkbox is checked.
* @property selectChecked
* @type {Boolean}
*/
__publicField(this, "selectChecked", !1);
/**
* GroupTotals, if any.
* @property totals
* @type {GroupTotals}
*/
__publicField(this, "totals", null);
/**
* Rows that are part of the group.
* @property rows
* @type {Array}
*/
__publicField(this, "rows", []);
/**
* Sub-groups that are part of the group.
* @property groups
* @type {Array}
*/
__publicField(this, "groups", null);
/**
* A unique key used to identify the group. This key can be used in calls to DataView
* collapseGroup() or expandGroup().
* @property groupingKey
* @type {Object}
*/
__publicField(this, "groupingKey", null);
}
/**
* Compares two Group instances.
* @method equals
* @return {Boolean}
* @param group {Group} Group instance to compare to.
*/
equals(group) {
return this.value === group.value && this.count === group.count && this.collapsed === group.collapsed && this.title === group.title;
}
}, SlickGroupTotals = class extends SlickNonDataItem {
constructor() {
super();
__publicField(this, "__groupTotals", !0);
/**
* Parent Group.
* @param group
* @type {Group}
*/
__publicField(this, "group", null);
/**
* Whether the totals have been fully initialized / calculated.
* Will be set to false for lazy-calculated group totals.
* @param initialized
* @type {Boolean}
*/
__publicField(this, "initialized", !1);
}
}, SlickEditorLock = class {
constructor() {
__publicField(this, "activeEditController", null);
}
/**
* Returns true if a specified edit controller is active (has the edit lock).
* If the parameter is not specified, returns true if any edit controller is active.
* @method isActive
* @param editController {EditController}
* @return {Boolean}
*/
isActive(editController) {
return editController ? this.activeEditController === editController : this.activeEditController !== null;
}
/**
* Sets the specified edit controller as the active edit controller (acquire edit lock).
* If another edit controller is already active, and exception will be throw new Error(.
* @method activate
* @param editController {EditController} edit controller acquiring the lock
*/
activate(editController) {
if (editController !== this.activeEditController) {
if (this.activeEditController !== null)
throw new Error("Slick.EditorLock.activate: an editController is still active, can't activate another editController");
if (!editController.commitCurrentEdit)
throw new Error("Slick.EditorLock.activate: editController must implement .commitCurrentEdit()");
if (!editController.cancelCurrentEdit)
throw new Error("Slick.EditorLock.activate: editController must implement .cancelCurrentEdit()");
this.activeEditController = editController;
}
}
/**
* Unsets the specified edit controller as the active edit controller (release edit lock).
* If the specified edit controller is not the active one, an exception will be throw new Error(.
* @method deactivate
* @param editController {EditController} edit controller releasing the lock
*/
deactivate(editController) {
if (this.activeEditController) {
if (this.activeEditController !== editController)
throw new Error("Slick.EditorLock.deactivate: specified editController is not the currently active one");
this.activeEditController = null;
}
}
/**
* Attempts to commit the current edit by calling "commitCurrentEdit" method on the active edit
* controller and returns whether the commit attempt was successful (commit may fail due to validation
* errors, etc.). Edit controller's "commitCurrentEdit" must return true if the commit has succeeded
* and false otherwise. If no edit controller is active, returns true.
* @method commitCurrentEdit
* @return {Boolean}
*/
commitCurrentEdit() {
return this.activeEditController ? this.activeEditController.commitCurrentEdit() : !0;
}
/**
* Attempts to cancel the current edit by calling "cancelCurrentEdit" method on the active edit
* controller and returns whether the edit was successfully cancelled. If no edit controller is
* active, returns true.
* @method cancelCurrentEdit
* @return {Boolean}
*/
cancelCurrentEdit() {
return this.activeEditController ? this.activeEditController.cancelCurrentEdit() : !0;
}
};
function regexSanitizer(dirtyHtml) {
return dirtyHtml.replace(/(\b)(on[a-z]+)(\s*)=|javascript:([^>]*)[^>]*|(<\s*)(\/*)script([<>]*).*(<\s*)(\/*)script(>*)|(<)(\/*)(script|script defer)(.*)(>|>">)/gi, "");
}
var BindingEventService = class {
constructor() {
__publicField(this, "_boundedEvents", []);
}
getBoundedEvents() {
return this._boundedEvents;
}
destroy() {
this.unbindAll();
}
/** Bind an event listener to any element */
bind(element, eventName, listener, options, groupName = "") {
element && (element.addEventListener(eventName, listener, options), this._boundedEvents.push({ element, eventName, listener, groupName }));
}
/** Unbind all will remove every every event handlers that were bounded earlier */
unbind(element, eventName, listener) {
element?.removeEventListener && element.removeEventListener(eventName, listener);
}
unbindByEventName(element, eventName) {
let boundedEvent = this._boundedEvents.find((e) => e.element === element && e.eventName === eventName);
boundedEvent && this.unbind(boundedEvent.element, boundedEvent.eventName, boundedEvent.listener);
}
/**
* Unbind all event listeners that were bounded, optionally provide a group name to unbind all listeners assigned to that specific group only.
*/
unbindAll(groupName) {
if (groupName) {
let groupNames = Array.isArray(groupName) ? groupName : [groupName];
for (let i = this._boundedEvents.length - 1; i >= 0; --i) {
let boundedEvent = this._boundedEvents[i];
if (groupNames.some((g) => g === boundedEvent.groupName)) {
let { element, eventName, listener } = boundedEvent;
this.unbind(element, eventName, listener), this._boundedEvents.splice(i, 1);
}
}
} else
for (; this._boundedEvents.length > 0; ) {
let boundedEvent = this._boundedEvents.pop(), { element, eventName, listener } = boundedEvent;
this.unbind(element, eventName, listener);
}
}
}, _Utils = class _Utils {
static isFunction(obj) {
return typeof obj == "function" && typeof obj.nodeType != "number" && typeof obj.item != "function";
}
static isPlainObject(obj) {
if (!obj || _Utils.toString.call(obj) !== "[object Object]")
return !1;
let proto = _Utils.getProto(obj);
if (!proto)
return !0;
let Ctor = _Utils.hasOwn.call(proto, "constructor") && proto.constructor;
return typeof Ctor == "function" && _Utils.fnToString.call(Ctor) === _Utils.ObjectFunctionString;
}
static calculateAvailableSpace(element) {
let bottom = 0, top = 0, left = 0, right = 0, windowHeight = window.innerHeight || 0, windowWidth = window.innerWidth || 0, scrollPosition = _Utils.windowScrollPosition(), pageScrollTop = scrollPosition.top, pageScrollLeft = scrollPosition.left, elmOffset = _Utils.offset(element);
if (elmOffset) {
let elementOffsetTop = elmOffset.top || 0, elementOffsetLeft = elmOffset.left || 0;
top = elementOffsetTop - pageScrollTop, bottom = windowHeight - (elementOffsetTop - pageScrollTop), left = elementOffsetLeft - pageScrollLeft, right = windowWidth - (elementOffsetLeft - pageScrollLeft);
}
return { top, bottom, left, right };
}
static extend(...args) {
let options, name, src, copy, copyIsArray, clone, target = args[0], i = 1, deep = !1, length = args.length;
for (typeof target == "boolean" ? (deep = target, target = args[i] || {}, i++) : target = target || {}, typeof target != "object" && !_Utils.isFunction(target) && (target = {}), i === length && (target = this, i--); i < length; i++)
if (_Utils.isDefined(options = args[i]))
for (name in options)
copy = options[name], !(name === "__proto__" || target === copy) && (deep && copy && (_Utils.isPlainObject(copy) || (copyIsArray = Array.isArray(copy))) ? (src = target[name], copyIsArray && !Array.isArray(src) ? clone = [] : !copyIsArray && !_Utils.isPlainObject(src) ? clone = {} : clone = src, copyIsArray = !1, target[name] = _Utils.extend(deep, clone, copy)) : copy !== void 0 && (target[name] = copy));
return target;
}
/**
* Create a DOM Element with any optional attributes or properties.
* It will only accept valid DOM element properties that `createElement` would accept.
* For example: `createDomElement('div', { className: 'my-css-class' })`,
* for style or dataset you need to use nested object `{ style: { display: 'none' }}
* The last argument is to optionally append the created element to a parent container element.
* @param {String} tagName - html tag
* @param {Object} options - element properties
* @param {[HTMLElement]} appendToParent - parent element to append to
*/
static createDomElement(tagName, elementOptions, appendToParent) {
let elm = document.createElement(tagName);
return elementOptions && Object.keys(elementOptions).forEach((elmOptionKey) => {
elmOptionKey === "innerHTML" && console.warn(`[SlickGrid] For better CSP (Content Security Policy) support, do not use "innerHTML" directly in "createDomElement('${tagName}', { innerHTML: 'some html'})", it is better as separate assignment: "const elm = createDomElement('span'); elm.innerHTML = 'some html';"`);
let elmValue = elementOptions[elmOptionKey];
typeof elmValue == "object" ? Object.assign(elm[elmOptionKey], elmValue) : elm[elmOptionKey] = elementOptions[elmOptionKey];
}), appendToParent?.appendChild && appendToParent.appendChild(elm), elm;
}
/**
* From any input provided, return the HTML string (when a string is provided, it will be returned "as is" but when it's a number it will be converted to string)
* When detecting HTMLElement/DocumentFragment, we can also specify which HTML type to retrieve innerHTML or outerHTML.
* We can get the HTML by looping through all fragment `childNodes`
* @param {DocumentFragment | HTMLElement | string | number} input
* @param {'innerHTML' | 'outerHTML'} [type] - when the input is a DocumentFragment or HTMLElement, which type of HTML do you want to return? 'innerHTML' or 'outerHTML'
* @returns {String}
*/
static getHtmlStringOutput(input, type = "innerHTML") {
return input instanceof DocumentFragment ? [].map.call(input.childNodes, (x) => x[type]).join("") || input.textContent || "" : input instanceof HTMLElement ? input[type] : String(input);
}
static emptyElement(element) {
for (; element?.firstChild; )
element.removeChild(element.firstChild);
return element;
}
/**
* Accepts string containing the class or space-separated list of classes, and
* returns list of individual classes.
* Method properly takes into account extra whitespaces in the `className`
* e.g.: " class1 class2 " => will result in `['class1', 'class2']`.
* @param {String} className - space separated list of class names
*/
static classNameToList(className = "") {
return className.split(" ").filter((cls) => cls);
}
static innerSize(elm, type) {
let size = 0;
if (elm) {
let clientSize = type === "height" ? "clientHeight" : "clientWidth", sides = type === "height" ? ["top", "bottom"] : ["left", "right"];
size = elm[clientSize];
for (let side of sides) {
let sideSize = parseFloat(_Utils.getElementProp(elm, `padding-${side}`) || "") || 0;
size -= sideSize;
}
}
return size;
}
static isDefined(value) {
return value != null && value !== "";
}
static getElementProp(elm, property) {
return elm?.getComputedStyle ? window.getComputedStyle(elm, null).getPropertyValue(property) : null;
}
/**
* Get the function details (param & body) of a function.
* It supports regular function and also ES6 arrow functions
* @param {Function} fn - function to analyze
* @param {Boolean} [addReturn] - when using ES6 function as single liner, we could add the missing `return ...`
* @returns
*/
static getFunctionDetails(fn, addReturn = !0) {
let isAsyncFn = !1, getFunctionBody = (func) => {
let fnStr = func.toString();
if (isAsyncFn = fnStr.includes("async "), fnStr.replaceAll(" ", "").includes("=>({")) {
let matches = fnStr.match(/(({.*}))/g) || [];
return matches.length >= 1 ? `return ${matches[0].trimStart()}` : fnStr;
}
let isOneLinerArrowFn = !fnStr.includes("{") && fnStr.includes("=>"), body = fnStr.substring(
fnStr.indexOf("{") + 1 || fnStr.indexOf("=>") + 2,
fnStr.includes("}") ? fnStr.lastIndexOf("}") : fnStr.length
);
return addReturn && isOneLinerArrowFn && !body.startsWith("return") ? "return " + body.trimStart() : body;
};
return {
params: ((func) => {
let STRIP_COMMENTS = /(\/\/.*$)|(\/\*[\s\S]*?\*\/)|(\s*=[^,)]*(('(?:\\'|[^'\r\n])*')|("(?:\\"|[^"\r\n])*"))|(\s*=[^,)]*))/mg, ARG_NAMES = /([^\s,]+)/g, fnStr = func.toString().replace(STRIP_COMMENTS, "");
return fnStr.slice(fnStr.indexOf("(") + 1, fnStr.indexOf(")")).match(ARG_NAMES) ?? [];
})(fn),
body: getFunctionBody(fn),
isAsync: isAsyncFn
};
}
static insertAfterElement(referenceNode, newNode) {
referenceNode.parentNode?.insertBefore(newNode, referenceNode.nextSibling);
}
static isEmptyObject(obj) {
return obj == null ? !0 : Object.entries(obj).length === 0;
}
static noop() {
}
static offset(el) {
if (!el || !el.getBoundingClientRect)
return;
let box = el.getBoundingClientRect(), docElem = document.documentElement;
return {
top: box.top + window.pageYOffset - docElem.clientTop,
left: box.left + window.pageXOffset - docElem.clientLeft
};
}
static windowScrollPosition() {
return {
left: window.pageXOffset || document.documentElement.scrollLeft || 0,
top: window.pageYOffset || document.documentElement.scrollTop || 0
};
}
static width(el, value) {
if (!(!el || !el.getBoundingClientRect)) {
if (value === void 0)
return el.getBoundingClientRect().width;
_Utils.setStyleSize(el, "width", value);
}
}
static height(el, value) {
if (el) {
if (value === void 0)
return el.getBoundingClientRect().height;
_Utils.setStyleSize(el, "height", value);
}
}
static setStyleSize(el, style, val) {
typeof val == "function" ? val = val() : typeof val == "string" ? el.style[style] = val : el.style[style] = val + "px";
}
static contains(parent, child) {
return !parent || !child ? !1 : !_Utils.parents(child).every((p) => parent !== p);
}
static isHidden(el) {
return el.offsetWidth === 0 && el.offsetHeight === 0;
}
static parents(el, selector) {
let parents = [], visible = selector === ":visible", hidden = selector === ":hidden";
for (; (el = el.parentNode) && el !== document && !(!el || !el.parentNode); )
hidden ? _Utils.isHidden(el) && parents.push(el) : visible ? _Utils.isHidden(el) || parents.push(el) : (!selector || el.matches(selector)) && parents.push(el);
return parents;
}
static toFloat(value) {
let x = parseFloat(value);
return isNaN(x) ? 0 : x;
}
static show(el, type = "") {
Array.isArray(el) ? el.forEach((e) => e.style.display = type) : el.style.display = type;
}
static hide(el) {
Array.isArray(el) ? el.forEach((e) => e.style.display = "none") : el.style.display = "none";
}
static slideUp(el, callback) {
return _Utils.slideAnimation(el, "slideUp", callback);
}
static slideDown(el, callback) {
return _Utils.slideAnimation(el, "slideDown", callback);
}
static slideAnimation(el, slideDirection, callback) {
if (window.jQuery !== void 0) {
window.jQuery(el)[slideDirection]("fast", callback);
return;
}
slideDirection === "slideUp" ? _Utils.hide(el) : _Utils.show(el), callback();
}
static applyDefaults(targetObj, srcObj) {
typeof srcObj == "object" && Object.keys(srcObj).forEach((key) => {
srcObj.hasOwnProperty(key) && !targetObj.hasOwnProperty(key) && (targetObj[key] = srcObj[key]);
});
}
/**
* User could optionally add PubSub Service to SlickEvent
* When it is defined then a SlickEvent `notify()` call will also dispatch it by using the PubSub publish() method
* @param {BasePubSub} [pubSubService]
* @param {*} scope
*/
static addSlickEventPubSubWhenDefined(pubSub, scope) {
if (pubSub)
for (let prop in scope)
scope[prop] instanceof SlickEvent && typeof scope[prop].setPubSubService == "function" && scope[prop].setPubSubService(pubSub);
}
};
// jQuery's extend
__publicField(_Utils, "getProto", Object.getPrototypeOf), __publicField(_Utils, "class2type", {}), __publicField(_Utils, "toString", _Utils.class2type.toString), __publicField(_Utils, "hasOwn", _Utils.class2type.hasOwnProperty), __publicField(_Utils, "fnToString", _Utils.hasOwn.toString), __publicField(_Utils, "ObjectFunctionString", _Utils.fnToString.call(Object)), __publicField(_Utils, "storage", {
// https://stackoverflow.com/questions/29222027/vanilla-alternative-to-jquery-data-function-any-native-javascript-alternati
_storage: /* @__PURE__ */ new WeakMap(),
// eslint-disable-next-line object-shorthand
put: function(element, key, obj) {
this._storage.has(element) || this._storage.set(element, /* @__PURE__ */ new Map()), this._storage.get(element).set(key, obj);
},
// eslint-disable-next-line object-shorthand
get: function(element, key) {
let el = this._storage.get(element);
return el ? el.get(key) : null;
},
// eslint-disable-next-line object-shorthand
remove: function(element, key) {
let ret = this._storage.get(element).delete(key);
return this._storage.get(element).size !== 0 && this._storage.delete(element), ret;
}
});
var Utils = _Utils, SlickGlobalEditorLock = new SlickEditorLock(), SlickCore = {
Event: SlickEvent,
EventData: SlickEventData,
EventHandler: SlickEventHandler,
Range: SlickRange,
NonDataRow: SlickNonDataItem,
Group: SlickGroup,
GroupTotals: SlickGroupTotals,
EditorLock: SlickEditorLock,
RegexSanitizer: regexSanitizer,
/**
* A global singleton editor lock.
* @class GlobalEditorLock
* @static
* @constructor
*/
GlobalEditorLock: SlickGlobalEditorLock,
keyCode: {
SPACE: 8,
BACKSPACE: 8,
DELETE: 46,
DOWN: 40,
END: 35,
ENTER: 13,
ESCAPE: 27,
HOME: 36,
INSERT: 45,
LEFT: 37,
PAGE_DOWN: 34,
PAGE_UP: 33,
RIGHT: 39,
TAB: 9,
UP: 38,
A: 65
},
preClickClassName: "slick-edit-preclick",
GridAutosizeColsMode: {
None: "NOA",
LegacyOff: "LOF",
LegacyForceFit: "LFF",
IgnoreViewport: "IGV",
FitColsToViewport: "FCV",
FitViewportToCols: "FVC"
},
ColAutosizeMode: {
Locked: "LCK",
Guide: "GUI",
Content: "CON",
ContentExpandOnly: "CXO",
ContentIntelligent: "CTI"
},
RowSelectionMode: {
FirstRow: "FS1",
FirstNRows: "FSN",
AllRows: "ALL",
LastRow: "LS1"
},
ValueFilterMode: {
None: "NONE",
DeDuplicate: "DEDP",
GetGreatestAndSub: "GR8T",
GetLongestTextAndSub: "LNSB",
GetLongestText: "LNSC"
},
WidthEvalMode: {
Auto: "AUTO",
TextOnly: "CANV",
HTML: "HTML"
}
}, {
EditorLock,
Event,
EventData,
EventHandler,
Group,
GroupTotals,
NonDataRow,
Range,
RegexSanitizer,
GlobalEditorLock,
keyCode,
preClickClassName,
GridAutosizeColsMode,
ColAutosizeMode,
RowSelectionMode,
ValueFilterMode,
WidthEvalMode
} = SlickCore;
// src/controls/slick.columnmenu.ts
var BindingEventService2 = BindingEventService, SlickEvent2 = Event, Utils2 = Utils, SlickColumnMenu = class {
constructor(columns, grid, options) {
this.columns = columns;
this.grid = grid;
// --
// public API
__publicField(this, "onColumnsChanged", new SlickEvent2("onColumnsChanged"));
// --
// protected props
__publicField(this, "_gridUid");
__publicField(this, "_columnTitleElm");
__publicField(this, "_listElm");
__publicField(this, "_menuElm");
__publicField(this, "_columnCheckboxes", []);
__publicField(this, "_bindingEventService", new BindingEventService2());
__publicField(this, "_options");
__publicField(this, "_defaults", {
fadeSpeed: 250,
// the last 2 checkboxes titles
hideForceFitButton: !1,
hideSyncResizeButton: !1,
forceFitTitle: "Force fit columns",
syncResizeTitle: "Synchronous resize",
headerColumnValueExtractor: (columnDef) => Utils2.getHtmlStringOutput(columnDef.name || "", "innerHTML")
});
this._gridUid = grid.getUID(), this._options = Utils2.extend({}, this._defaults, options), this.init(this.grid);
}
init(grid) {
Utils2.addSlickEventPubSubWhenDefined(grid.getPubSubService(), this), grid.onHeaderContextMenu.subscribe(this.handleHeaderContextMenu.bind(this)), grid.onColumnsReordered.subscribe(this.updateColumnOrder.bind(this)), this._menuElm = document.createElement("div"), this._menuElm.className = `slick-columnpicker ${this._gridUid}`, this._menuElm.style.display = "none", document.body.appendChild(this._menuElm);
let buttonElm = document.createElement("button");
buttonElm.type = "button", buttonElm.className = "close", buttonElm.dataset.dismiss = "slick-columnpicker", buttonElm.ariaLabel = "Close";
let spanCloseElm = document.createElement("span");
if (spanCloseElm.className = "close", spanCloseElm.ariaHidden = "true", spanCloseElm.textContent = "\xD7", buttonElm.appendChild(spanCloseElm), this._menuElm.appendChild(buttonElm), this._options.columnPickerTitle || this._options.columnPicker?.columnTitle) {
let columnTitle = this._options.columnPickerTitle || this._options.columnPicker?.columnTitle;
this._columnTitleElm = document.createElement("div"), this._columnTitleElm.className = "slick-gridmenu-custom", this._columnTitleElm.textContent = columnTitle || "", this._menuElm.appendChild(this._columnTitleElm);
}
this._bindingEventService.bind(this._menuElm, "click", this.updateColumn.bind(this)), this._listElm = document.createElement("span"), this._listElm.className = "slick-columnpicker-list", this._bindingEventService.bind(document.body, "mousedown", this.handleBodyMouseDown.bind(this)), this._bindingEventService.bind(document.body, "beforeunload", this.destroy.bind(this));
}
destroy() {
this.grid.onHeaderContextMenu.unsubscribe(this.handleHeaderContextMenu.bind(this)), this.grid.onColumnsReordered.unsubscribe(this.updateColumnOrder.bind(this)), this._bindingEventService.unbindAll(), this._listElm?.remove(), this._menuElm?.remove();
}
handleBodyMouseDown(e) {
(this._menuElm !== e.target && !(this._menuElm && this._menuElm.contains(e.target)) || e.target.className === "close") && (this._menuElm.setAttribute("aria-expanded", "false"), this._menuElm.style.display = "none");
}
handleHeaderContextMenu(e) {
e.preventDefault(), Utils2.emptyElement(this._listElm), this.updateColumnOrder(), this._columnCheckboxes = [];
let columnId, columnLabel, excludeCssClass;
for (let i = 0; i < this.columns.length; i++) {
columnId = this.columns[i].id;
let colName = this.columns[i].name instanceof HTMLElement ? this.columns[i].name.innerHTML : this.columns[i].name || "";
excludeCssClass = this.columns[i].excludeFromColumnPicker ? "hidden" : "";
let liElm = document.createElement("li");
liElm.className = excludeCssClass, liElm.ariaLabel = colName;
let checkboxElm = document.createElement("input");
checkboxElm.type = "checkbox", checkboxElm.id = `${this._gridUid}colpicker-${columnId}`, checkboxElm.dataset.columnid = String(this.columns[i].id), liElm.appendChild(checkboxElm), this._columnCheckboxes.push(checkboxElm), Utils2.isDefined(this.grid.getColumnIndex(columnId)) && !this.columns[i].hidden && (checkboxElm.checked = !0), columnLabel = this._options?.columnPicker?.headerColumnValueExtractor ? this._options.columnPicker.headerColumnValueExtractor(this.columns[i], this._options) : this._defaults.headerColumnValueExtractor(this.columns[i], this._options);
let labelElm = document.createElement("label");
labelElm.htmlFor = `${this._gridUid}colpicker-${columnId}`, this.grid.applyHtmlCode(labelElm, columnLabel), liElm.appendChild(labelElm), this._listElm.appendChild(liElm);
}
if (this._options.columnPicker && (!this._options.columnPicker.hideForceFitButton || !this._options.columnPicker.hideSyncResizeButton) && this._listElm.appendChild(document.createElement("hr")), !this._options.columnPicker?.hideForceFitButton) {
let forceFitTitle = this._options.columnPicker?.forceFitTitle || this._options.forceFitTitle, liElm = document.createElement("li");
liElm.ariaLabel = forceFitTitle || "", this._listElm.appendChild(liElm);
let forceFitCheckboxElm = document.createElement("input");
forceFitCheckboxElm.type = "checkbox", forceFitCheckboxElm.id = `${this._gridUid}colpicker-forcefit`, forceFitCheckboxElm.dataset.option = "autoresize", liElm.appendChild(forceFitCheckboxElm);
let labelElm = document.createElement("label");
labelElm.htmlFor = `${this._gridUid}colpicker-forcefit`, labelElm.textContent = forceFitTitle || "", liElm.appendChild(labelElm), this.grid.getOptions().forceFitColumns && (forceFitCheckboxElm.checked = !0);
}
if (!this._options.columnPicker?.hideSyncResizeButton) {
let syncResizeTitle = this._options.columnPicker?.syncResizeTitle || this._options.syncResizeTitle, liElm = document.createElement("li");
liElm.ariaLabel = syncResizeTitle || "", this._listElm.appendChild(liElm);
let syncResizeCheckboxElm = document.createElement("input");
syncResizeCheckboxElm.type = "checkbox", syncResizeCheckboxElm.id = `${this._gridUid}colpicker-syncresize`, syncResizeCheckboxElm.dataset.option = "syncresize", liElm.appendChild(syncResizeCheckboxElm);
let labelElm = document.createElement("label");
labelElm.htmlFor = `${this._gridUid}colpicker-syncresize`, labelElm.textContent = syncResizeTitle || "", liElm.appendChild(labelElm), this.grid.getOptions().syncColumnCellResize && (syncResizeCheckboxElm.checked = !0);
}
this.repositionMenu(e);
}
repositionMenu(event2) {
let targetEvent = event2?.touches?.[0] || event2;
this._menuElm.style.top = `${targetEvent.pageY - 10}px`, this._menuElm.style.left = `${targetEvent.pageX - 10}px`, this._menuElm.style.maxHeight = `${window.innerHeight - targetEvent.clientY}px`, this._menuElm.style.display = "block", this._menuElm.setAttribute("aria-expanded", "true"), this._menuElm.appendChild(this._listElm);
}
updateColumnOrder() {
let current = this.grid.getColumns().slice(0), ordered = new Array(this.columns.length);
for (let i = 0; i < ordered.length; i++)
this.grid.getColumnIndex(this.columns[i].id) === void 0 ? ordered[i] = this.columns[i] : ordered[i] = current.shift();
this.columns = ordered;
}
/** Update the Titles of each sections (command, customTitle, ...) */
updateAllTitles(pickerOptions) {
this.grid.applyHtmlCode(this._columnTitleElm, pickerOptions.columnTitle);
}
updateColumn(e) {
if (e.target.dataset.option === "autoresize") {
let previousVisibleColumns = this.getVisibleColumns(), isChecked = e.target.checked;
this.grid.setOptions({ forceFitColumns: isChecked }), this.grid.setColumns(previousVisibleColumns);
return;
}
if (e.target.dataset.option === "syncresize") {
e.target.checked ? this.grid.setOptions({ syncColumnCellResize: !0 }) : this.grid.setOptions({ syncColumnCellResize: !1 });
return;
}
if (e.target.type === "checkbox") {
let isChecked = e.target.checked, columnId = e.target.dataset.columnid || "", visibleColumns = [];
if (this._columnCheckboxes.forEach((columnCheckbox, idx) => {
this.columns[idx].hidden !== void 0 && (this.columns[idx].hidden = !columnCheckbox.checked), columnCheckbox.checked && visibleColumns.push(this.columns[idx]);
}), !visibleColumns.length) {
e.target.checked = !0;
return;
}
this.grid.setColumns(visibleColumns), this.onColumnsChanged.notify({ columnId, showing: isChecked, allColumns: this.columns, columns: this.columns, visibleColumns, grid: this.grid });
}
}
/** @deprecated because of a typo @use `setColumnVisibility()` instead */
setColumnVisibiliy(idxOrId, show) {
this.setColumnVisibility(idxOrId, show);
}
setColumnVisibility(idxOrId, show) {
let idx = typeof idxOrId == "number" ? idxOrId : this.getColumnIndexbyId(idxOrId), visibleColumns = this.getVisibleColumns(), col = this.columns[idx];
if (show)
col.hidden = !1, visibleColumns.splice(idx, 0, col);
else {
let newVisibleColumns = [];
for (let i = 0; i < visibleColumns.length; i++)
visibleColumns[i].id !== col.id && newVisibleColumns.push(visibleColumns[i]);
visibleColumns = newVisibleColumns;
}
this.grid.setColumns(visibleColumns), this.onColumnsChanged.notify({ columnId: col.id, showing: show, allColumns: this.columns, columns: this.columns, visibleColumns, grid: this.grid });
}
getAllColumns() {
return this.columns;
}
getColumnbyId(id) {
for (let i = 0; i < this.columns.length; i++)
if (this.columns[i].id === id)
return this.columns[i];
return null;
}
getColumnIndexbyId(id) {
for (let i = 0; i < this.columns.length; i++)
if (this.columns[i].id === id)
return i;
return -1;
}
/** visible columns, we can simply get them directly from the grid */
getVisibleColumns() {
return this.grid.getColumns();
}
};
// src/controls/slick.columnpicker.ts
var BindingEventService3 = BindingEventService, SlickEvent3 = Event, Utils3 = Utils, SlickColumnPicker = class {
constructor(columns, grid, gridOptions) {
this.columns = columns;
this.grid = grid;
// --
// public API
__publicField(this, "onColumnsChanged", new SlickEvent3("onColumnsChanged"));
// --
// protected props
__publicField(this, "_gridUid");
__publicField(this, "_columnTitleElm");
__publicField(this, "_listElm");
__publicField(this, "_menuElm");
__publicField(this, "_columnCheckboxes", []);
__publicField(this, "_bindingEventService", new BindingEventService3());
__publicField(this, "_gridOptions");
__publicField(this, "_defaults", {
fadeSpeed: 250,
// the last 2 checkboxes titles
hideForceFitButton: !1,
hideSyncResizeButton: !1,
forceFitTitle: "Force fit columns",
syncResizeTitle: "Synchronous resize",
headerColumnValueExtractor: (columnDef) => Utils3.getHtmlStringOutput(columnDef.name || "", "innerHTML")
});
this._gridUid = grid.getUID(), this._gridOptions = Utils3.extend({}, this._defaults, gridOptions), this.init(this.grid);
}
init(grid) {
Utils3.addSlickEventPubSubWhenDefined(grid.getPubSubService(), this), grid.onColumnsReordered.subscribe(this.updateColumnOrder.bind(this)), grid.onHeaderContextMenu.subscribe(this.handleHeaderContextMenu.bind(this)), grid.onPreHeaderContextMenu.subscribe((e) => {
["slick-column-name", "slick-header-column"].some((className) => e.target?.classList.contains(className)) && this.handleHeaderContextMenu(e);
}), this._menuElm = document.createElement("div"), this._menuElm.className = `slick-columnpicker ${this._gridUid}`, this._menuElm.style.display = "none", document.body.appendChild(this._menuElm);
let buttonElm = document.createElement("button");
buttonElm.type = "button", buttonElm.className = "close", buttonElm.dataset.dismiss = "slick-columnpicker", buttonElm.ariaLabel = "Close";
let spanCloseElm = document.createElement("span");
if (spanCloseElm.className = "close", spanCloseElm.ariaHidden = "true", spanCloseElm.textContent = "\xD7", buttonElm.appendChild(spanCloseElm), this._menuElm.appendChild(buttonElm), this._gridOptions.columnPickerTitle || this._gridOptions.columnPicker?.columnTitle) {
let columnTitle = this._gridOptions.columnPickerTitle || this._gridOptions.columnPicker?.columnTitle;
this._columnTitleElm = document.createElement("div"), this._columnTitleElm.className = "slick-gridmenu-custom", this._columnTitleElm.textContent = columnTitle || "", this._menuElm.appendChild(this._columnTitleElm);
}
this._bindingEventService.bind(this._menuElm, "click", this.updateColumn.bind(this)), this._listElm = document.createElement("span"), this._listElm.className = "slick-columnpicker-list", this._bindingEventService.bind(document.body, "mousedown", this.handleBodyMouseDown.bind(this)), this._bindingEventService.bind(document.body, "beforeunload", this.destroy.bind(this));
}
destroy() {
this.grid.onPreHeaderContextMenu.unsubscribe(this.handleHeaderContextMenu.bind(this)), this.grid.onHeaderContextMenu.unsubscribe(this.handleHeaderContextMenu.bind(this)), this.grid.onColumnsReordered.unsubscribe(this.updateColumnOrder.bind(this)), this._bindingEventService.unbindAll(), this._listElm?.remove(), this._menuElm?.remove();
}
handleBodyMouseDown(e) {
(this._menuElm !== e.target && !this._menuElm?.contains(e.target) || e.target.className === "close") && (this._menuElm.setAttribute("aria-expanded", "false"), this._menuElm.style.display = "none");
}
handleHeaderContextMenu(e) {
e.preventDefault(), Utils3.emptyElement(this._listElm), this.updateColumnOrder(), this._columnCheckboxes = [];
let columnId, columnLabel, excludeCssClass;
for (let i = 0; i < this.columns.length; i++) {
columnId = this.columns[i].id;
let colName = this.columns[i].name instanceof HTMLElement ? this.columns[i].name.innerHTML : this.columns[i].name || "";
excludeCssClass = this.columns[i].excludeFromColumnPicker ? "hidden" : "";
let liElm = document.createElement("li");
liElm.className = excludeCssClass, liElm.ariaLabel = colName;
let checkboxElm = document.createElement("input");
checkboxElm.type = "checkbox", checkboxElm.id = `${this._gridUid}colpicker-${columnId}`, checkboxElm.dataset.columnid = String(this.columns[i].id), liElm.appendChild(checkboxElm), this._columnCheckboxes.push(checkboxElm), Utils3.isDefined(this.grid.getColumnIndex(columnId)) && !this.columns[i].hidden && (checkboxElm.checked = !0), columnLabel = this._gridOptions?.columnPicker?.headerColumnValueExtractor ? this._gridOptions.columnPicker.headerColumnValueExtractor(this.columns[i], this._gridOptions) : this._defaults.headerColumnValueExtractor(this.columns[i], this._gridOptions);
let labelElm = document.createElement("label");
labelElm.htmlFor = `${this._gridUid}colpicker-${columnId}`, this.grid.applyHtmlCode(labelElm, columnLabel), liElm.appendChild(labelElm), this._listElm.appendChild(liElm);
}
if (this._gridOptions.columnPicker && (!this._gridOptions.columnPicker.hideForceFitButton || !this._gridOptions.columnPicker.hideSyncResizeButton) && this._listElm.appendChild(document.createElement("hr")), !this._gridOptions.columnPicker?.hideForceFitButton) {
let forceFitTitle = this._gridOptions.columnPicker?.forceFitTitle || this._gridOptions.forceFitTitle, liElm = document.createElement("li");
liElm.ariaLabel = forceFitTitle || "", this._listElm.appendChild(liElm);
let forceFitCheckboxElm = document.createElement("input");
forceFitCheckboxElm.type = "checkbox", forceFitCheckboxElm.id = `${this._gridUid}colpicker-forcefit`, forceFitCheckboxElm.dataset.option = "autoresize", liElm.appendChild(forceFitCheckboxElm);
let labelElm = document.createElement("label");
labelElm.htmlFor = `${this._gridUid}colpicker-forcefit`, labelElm.textContent = forceFitTitle || "", liElm.appendChild(labelElm), this.grid.getOptions().forceFitColumns && (forceFitCheckboxElm.checked = !0);
}
if (!this._gridOptions.columnPicker?.hideSyncResizeButton) {
let syncResizeTitle = this._gridOptions.columnPicker?.syncResizeTitle || this._gridOptions.syncResizeTitle, liElm = document.createElement("li");
liElm.ariaLabel = syncResizeTitle || "", this._listElm.appendChild(liElm);
let syncResizeCheckboxElm = document.createElement("input");
syncResizeCheckboxElm.type = "checkbox", syncResizeCheckboxElm.id = `${this._gridUid}colpicker-syncresize`, syncResizeCheckboxElm.dataset.option = "syncresize", liElm.appendChild(syncResizeCheckboxElm);
let labelElm = document.createElement("label");
labelElm.htmlFor = `${this._gridUid}colpicker-syncresize`, labelElm.textContent = syncResizeTitle || "", liElm.appendChild(labelElm), this.grid.getOptions().syncColumnCellResize && (syncResizeCheckboxElm.checked = !0);
}
this.repositionMenu(e);
}
repositionMenu(event2) {
let targetEvent = event2?.touches?.[0] ?? event2;
if (this._menuElm) {
this._menuElm.style.display = "block";
let gridPos = this.grid.getGridPosition(), menuWidth = this._menuElm.clientWidth || 0, menuOffsetLeft = targetEvent.pageX || 0;
gridPos?.width && menuOffsetLeft + menuWidth >= gridPos.width && (menuOffsetLeft = menuOffsetLeft - menuWidth), this._menuElm.style.top = `${targetEvent.pageY - 10}px`, this._menuElm.style.left = `${menuOffsetLeft}px`, this._menuElm.style.maxHeight = `${window.innerHeight - targetEvent.clientY}px`, this._menuElm.setAttribute("aria-expanded", "true"), this._menuElm.appendChild(this._listElm);
}
}
updateColumnOrder() {
let current = this.grid.getColumns().slice(0), ordered = new Array(this.columns.length);
for (let i = 0; i < ordered.length; i++)
this.grid.getColumnIndex(this.columns[i].id) === void 0 ? ordered[i] = this.columns[i] : ordered[i] = current.shift();
this.columns = ordered;
}
/** Update the Titles of each sections (command, customTitle, ...) */
updateAllTitles(pickerOptions) {
this.grid.applyHtmlCode(this._columnTitleElm, pickerOptions.columnTitle);
}
updateColumn(e) {
if (e.target.dataset.option === "autoresize") {
let previousVisibleColumns = this.getVisibleColumns(), isChecked = e.target.checked || !1;
this.grid.setOptions({ forceFitColumns: isChecked }), this.grid.setColumns(previousVisibleColumns);
return;
}
if (e.target.dataset.option === "syncresize") {
e.target.checked ? this.grid.setOptions({ syncColumnCellResize: !0 }) : this.grid.setOptions({ syncColumnCellResize: !1 });
return;
}
if (e.target.type === "checkbox") {
let isChecked = e.target.checked, columnId = e.target.dataset.columnid || "", visibleColumns = [];
if (this._columnCheckboxes.forEach((columnCheckbox, idx) => {
this.columns[idx].hidden !== void 0 && (this.columns[idx].hidden = !columnCheckbox.checked), columnCheckbox.checked && visibleColumns.push(this.columns[idx]);
}), !visibleColumns.length) {
e.target.checked = !0;
return;
}
this.grid.setColumns(visibleColumns), this.onColumnsChanged.notify({ columnId, showing: isChecked, allColumns: this.columns, columns: this.columns, visibleColumns, grid: this.grid });
}
}
/** @deprecated because of a typo @use `setColumnVisibility()` instead */
setColumnVisibiliy(idxOrId, show) {
this.setColumnVisibility(idxOrId, show);
}
setColumnVisibility(idxOrId, show) {
let idx = typeof idxOrId == "number" ? idxOrId : this.getColumnIndexbyId(idxOrId), visibleColumns = this.getVisibleColumns(), col = this.columns[idx];
if (show)
col.hidden = !1, visibleColumns.splice(idx, 0, col);
else {
let newVisibleColumns = [];
for (let i = 0; i < visibleColumns.length; i++)
visibleColumns[i].id !== col.id && newVisibleColumns.push(visibleColumns[i]);
visibleColumns = newVisibleColumns;
}
this.grid.setColumns(visibleColumns), this.onColumnsChanged.notify({ columnId: col.id, showing: show, allColumns: this.columns, columns: this.columns, visibleColumns, grid: this.grid });
}
getAllColumns() {
return this.columns;
}
getColumnbyId(id) {
for (let i = 0; i < this.columns.length; i++)
if (this.columns[i].id === id)
return this.columns[i];
return null;
}
getColumnIndexbyId(id) {
for (let i = 0; i < this.columns.length; i++)
if (this.columns[i].id === id)
return i;
return -1;
}
/** visible columns, we can simply get them directly from the grid */
getVisibleColumns() {
return this.grid.getColumns();
}
};
// src/controls/slick.gridmenu.ts
var BindingEventService4 = BindingEventService, SlickEvent4 = SlickEvent, Utils4 = Utils, SlickGridMenu = class {
constructor(columns, grid, gridOptions) {
this.columns = columns;
this.grid = grid;
// --
// public API
__publicField(this, "onAfterMenuShow", new SlickEvent4("onAfterMenuShow"));
__publicField(this, "onBeforeMenuShow", new SlickEvent4("onBeforeMenuShow"));
__publicField(this, "onMenuClose", new SlickEvent4("onMenuClose"));
__publicField(this, "onCommand", new SlickEvent4("onCommand"));
__publicField(this, "onColumnsChanged", new SlickEvent4("onColumnsChanged"));
// --
// protected props
__publicField(this, "_bindingEventService");
__publicField(this, "_gridOptions");
__publicField(this, "_gridUid");
__publicField(this, "_isMenuOpen", !1);
__publicField(this, "_columnCheckboxes", []);
__publicField(this, "_columnTitleElm");
__publicField(this, "_commandTitleElm");
__publicField(this, "_commandListElm");
__publicField(this, "_headerElm", null);
__publicField(this, "_listElm");
__publicField(this, "_buttonElm");
__publicField(this, "_menuElm");
__publicField(this, "_subMenuParentId", "");
__publicField(this, "_gridMenuOptions", null);
__publicField(this, "_defaults", {
showButton: !0,
hideForceFitButton: !1,
hideSyncResizeButton: !1,
forceFitTitle: "Force fit columns",
marginBottom: 15,
menuWidth: 18,
contentMinWidth: 0,
resizeOnShowHeaderRow: !1,
subMenuOpenByEvent: "mouseover",
syncResizeTitle: "Synchronous resize",
useClickToRepositionMenu: !0,
headerColumnValueExtractor: (columnDef) => Utils4.getHtmlStringOutput(columnDef.name || "", "innerHTML")
});
this._gridUid = grid.getUID(), this._gridOptions = gridOptions, this._gridMenuOptions = Utils4.extend({}, this._defaults, gridOptions.gridMenu), this._bindingEventService = new BindingEventService4(), grid.onSetOptions.subscribe((_e, args) => {
if (args && args.optionsBefore && args.optionsAfter) {
let switchedFromRegularToFrozen = args.optionsBefore.frozenColumn >= 0 && args.optionsAfter.frozenColumn === -1, switchedFromFrozenToRegular = args.optionsBefore.frozenColumn === -1 && args.optionsAfter.frozenColumn >= 0;
(switchedFromRegularToFrozen || switchedFromFrozenToRegular) && this.recreateGridMenu();
}
}), this.init(this.grid);
}
init(grid) {
this._gridOptions = grid.getOptions(), Utils4.addSlickEventPubSubWhenDefined(grid.getPubSubService(), this), this.createGridMenu(), (this._gridMenuOptions?.customItems || this._gridMenuOptions?.customTitle) && console.warn('[SlickGrid] Grid Menu "customItems" and "customTitle" were deprecated to align with other Menu plugins, please use "commandItems" and "commandTitle" instead.'), grid.onBeforeDestroy.subscribe(this.destroy.bind(this));
}
setOptions(newOptions) {
this._gridMenuOptions = Utils4.extend({}, this._gridMenuOptions, newOptions);
}
createGridMenu() {
let gridMenuWidth = this._gridMenuOptions?.menuWidth || this._defaults.menuWidth;
if (this._gridOptions && this._gridOptions.hasOwnProperty("frozenColumn") && this._gridOptions.frozenColumn >= 0 ? this._headerElm = document.querySelector(`.${this._gridUid} .slick-header-right`) : this._headerElm = document.querySelector(`.${this._gridUid} .slick-header-left`), this._headerElm.style.width = `calc(100% - ${gridMenuWidth}px)`, (Utils4.isDefined(this._gridMenuOptions?.resizeOnShowHeaderRow) ? this._gridMenuOptions.resizeOnShowHeaderRow : this._defaults.resizeOnShowHeaderRow) && this._gridOptions.showHeaderRow) {
let headerRow = document.querySelector(`.${this._gridUid}.slick-headerrow`);
headerRow && (headerRow.style.width = `calc(100% - ${gridMenuWidth}px)`);
}
if (this._gridMenuOptions?.showButton !== void 0 ? this._gridMenuOptions.showButton : this._defaults.showButton) {
if (this._buttonElm = document.createElement("button"), this._buttonElm.className = "slick-gridmenu-button", this._buttonElm.ariaLabel = "Grid Menu", this._gridMenuOptions?.iconCssClass)
this._buttonElm.classList.add(...Utils4.classNameToList(this._gridMenuOptions.iconCssClass));
else {
let iconImageElm = document.createElement("img");
iconImageElm.src = this._gridMenuOptions?.iconImage ? this._gridMenuOptions.iconImage : "../images/drag-handle.png", this._buttonElm.appendChild(iconImageElm);
}
let buttonContainerTarget = this._gridMenuOptions?.iconButtonContainer === "preheader" ? "firstChild" : "lastChild";
this._headerElm.parentElement.insertBefore(this._buttonElm, this._headerElm.parentElement[buttonContainerTarget]), this._bindingEventService.bind(this._buttonElm, "click", this.showGridMenu.bind(this));
}
this._menuElm = this.createMenu(0), this.populateColumnPicker(), document.body.appendChild(this._menuElm), this._bindingEventService.bind(document.body, "mousedown", this.handleBodyMouseDown.bind(this)), this._bindingEventService.bind(document.body, "beforeunload", this.destroy.bind(this));
}
/** Create the menu or sub-menu(s) but without the column picker which is a separate single process */
createMenu(level = 0, item) {
let maxHeight = isNaN(this._gridMenuOptions?.maxHeight) ? this._gridMenuOptions?.maxHeight : `${this._gridMenuOptions?.maxHeight ?? 0}px`, width = isNaN(this._gridMenuOptions?.width) ? this._gridMenuOptions?.width : `${this._gridMenuOptions?.maxWidth ?? 0}px`, subMenuCommand = item?.command, subMenuId = level === 1 && subMenuCommand ? subMenuCommand.replaceAll(" ", "") : "";
subMenuId && (this._subMenuParentId = subMenuId), level > 1 && (subMenuId = this._subMenuParentId);
let menuClasses = `slick-gridmenu slick-menu-level-${level} ${this._gridUid}`, bodyMenuElm = document.body.querySelector(`.slick-gridmenu.slick-menu-level-${level}${this.getGridUidSelector()}`);
if (bodyMenuElm) {
if (bodyMenuElm.dataset.subMenuParent === subMenuId)
return bodyMenuElm;
this.destroySubMenus();
}
let menuElm = document.createElement("div");
menuElm.role = "menu", menuElm.className = menuClasses, level > 0 && (menuElm.classList.add("slick-submenu"), subMenuId && (menuElm.dataset.subMenuParent = subMenuId)), menuElm.ariaLabel = level > 1 ? "SubMenu" : "Grid Menu", width && (menuElm.style.width = width), maxHeight && (menuElm.style.maxHeight = maxHeight), menuElm.style.display = "none";
let closeButtonElm = null;
if (level === 0) {
closeButtonElm = document.createElement("button"), closeButtonElm.type = "button", closeButtonElm.className = "close", closeButtonElm.dataset.dismiss = "slick-gridmenu", closeButtonElm.ariaLabel = "Close";
let spanCloseElm = document.createElement("span");
spanCloseElm.className = "close", spanCloseElm.ariaHidden = "true", spanCloseElm.textContent = "\xD7", closeButtonElm.appendChild(spanCloseElm), menuElm.appendChild(closeButtonElm);
}
this._commandListElm = document.createElement("div"), this._commandListElm.className = `slick-gridmenu-custom slick-gridmenu-command-list slick-menu-level-${level}`, this._commandListElm.role = "menu", menuElm.appendChild(this._commandListElm);
let commandItems = item?.commandItems ?? item?.customItems ?? this._gridMenuOptions?.commandItems ?? this._gridMenuOptions?.customItems ?? [];
return commandItems.length > 0 && item && level > 0 && this.addSubMenuTitleWhenExists(item, this._commandListElm), this.populateCommandsMenu(commandItems, this._commandListElm, { grid: this.grid, level }), level++, menuElm;
}
/** Destroy the plugin by unsubscribing every events & also delete the menu DOM elements */
destroy() {
this.onAfterMenuShow.unsubscribe(), this.onBeforeMenuShow.unsubscribe(), this.onMenuClose.unsubscribe(), this.onCommand.unsubscribe(), this.onColumnsChanged.unsubscribe(), this.grid.onColumnsReordered.unsubscribe(this.updateColumnOrder.bind(this)), this.grid.onBeforeDestroy.unsubscribe(), this.grid.onSetOptions.unsubscribe(), this._bindingEventService.unbindAll(), this._menuElm?.remove(), this.deleteMenu();
}
/** Delete the menu DOM element but without unsubscribing any events */
deleteMenu() {
this._bindingEventService.unbindAll();
let gridMenuElm = document.querySelector(`div.slick-gridmenu.${this._gridUid}`);
gridMenuElm && (gridMenuElm.style.display = "none"), this._headerElm && (this._headerElm.style.width = "100%"), this._buttonElm?.remove(), this._menuElm?.remove();
}
/** Close and destroy all previously opened sub-menus */
destroySubMenus() {
this._bindingEventService.unbindAll("sub-menu"), document.querySelectorAll(`.slick-gridmenu.slick-submenu${this.getGridUidSelector()}`).forEach((subElm) => subElm.remove());
}
/** Construct the custom command menu items. */
populateCommandsMenu(commandItems, commandListElm, args) {
let level = args?.level || 0, isSubMenu = level > 0;
!isSubMenu && (this._gridMenuOptions?.commandTitle || this._gridMenuOptions?.customTitle) && (this._commandTitleElm = document.createElement("div"), this._commandTitleElm.className = "title", this.grid.applyHtmlCode(this._commandTitleElm, this.grid.sanitizeHtmlString(this._gridMenuOptions.commandTitle || this._gridMenuOptions.customTitle)), commandListElm.appendChild(this._commandTitleElm));
for (let i = 0, ln = commandItems.length; i < ln; i++) {
let addClickListener = !0, item = commandItems[i], callbackArgs = {
grid: this.grid,
menu: this._menuElm,
columns: this.columns,
visibleColumns: this.getVisibleColumns()
}, isItemVisible = this.runOverrideFunctionWhenExists(item.itemVisibilityOverride, callbackArgs), isItemUsable = this.runOverrideFunctionWhenExists(item.itemUsabilityOverride, callbackArgs);
if (!isItemVisible)
continue;
Object.prototype.hasOwnProperty.call(item, "itemUsabilityOverride") && (item.disabled = !isItemUsable);
let liElm = document.createElement("div");
liElm.className = "slick-gridmenu-item", liElm.role = "menuitem", (item.divider || item === "divider") && (liElm.classList.add("slick-gridmenu-item-divider"), addClickListener = !1), item.disabled && liElm.classList.add("slick-gridmenu-item-disabled"), item.hidden && liElm.classList.add("slick-gridmenu-item-hidden"), item.cssClass && liElm.classList.add(...Utils4.classNameToList(item.cssClass)), item.tooltip && (liElm.title = item.tooltip || "");
let iconElm = document.createElement("div");
iconElm.className = "slick-gridmenu-icon", liElm.appendChild(iconElm), item.iconCssClass && iconElm.classList.add(...Utils4.classNameToList(item.iconCssClass)), item.iconImage && (iconElm.style.backgroundImage = `url(${item.iconImage})`);
let textElm = document.createElement("span");
if (textElm.className = "slick-gridmenu-content", this.grid.applyHtmlCode(textElm, this.grid.sanitizeHtmlString(item.title || "")), liElm.appendChild(textElm), item.textCssClass && textElm.classList.add(...Utils4.classNameToList(item.textCssClass)), commandListElm.appendChild(liElm), addClickListener) {
let eventGroup = isSubMenu ? "sub-menu" : "parent-menu";
this._bindingEventService.bind(liElm, "click", this.handleMenuItemClick.bind(this, item, level), void 0, eventGroup);
}
if (this._gridMenuOptions?.subMenuOpenByEvent === "mouseover" && this._bindingEventService.bind(liElm, "mouseover", (e) => {
item.commandItems || item.customItems ? this.repositionSubMenu(item, level, e) : isSubMenu || this.destroySubMenus();
}), item.commandItems || item.customItems) {
let chevronElm = document.createElement("span");
chevronElm.className = "sub-item-chevron", this._gridMenuOptions?.subItemChevronClass ? chevronElm.classList.add(...Utils4.classNameToList(this._gridMenuOptions.subItemChevronClass)) : chevronElm.textContent = "\u2B9E", liElm.classList.add("slick-submenu-item"), liElm.appendChild(chevronElm);
continue;
}
}
}
/** Build the column picker, the code comes almost untouched from the file "slick.columnpicker.js" */
populateColumnPicker() {
this.grid.onColumnsReordered.subscribe(this.updateColumnOrder.bind(this)), this._gridMenuOptions?.columnTitle && (this._columnTitleElm = document.createElement("div"), this._columnTitleElm.className = "title", this.grid.applyHtmlCode(this._columnTitleElm, this.grid.sanitizeHtmlString(this._gridMenuOptions.columnTitle)), this._menuElm.appendChild(this._columnTitleElm)), this._bindingEventService.bind(this._menuElm, "click", this.updateColumn.bind(this)), this._listElm = document.createElement("span"), this._listElm.className = "slick-gridmenu-list", this._listElm.role = "menu";
}
/** Delete and then Recreate the Grid Menu (for example when we switch from regular to a frozen grid) */
recreateGridMenu() {
this.deleteMenu(), this.init(this.grid);
}
showGridMenu(e) {
let targetEvent = e.touches ? e.touches[0] : e;
e.preventDefault(), Utils4.emptyElement(this._listElm), Utils4.emptyElement(this._commandListElm);
let commandItems = this._gridMenuOptions?.commandItems ?? this._gridMenuOptions?.customItems ?? [];
this.populateCommandsMenu(commandItems, this._commandListElm, { grid: this.grid, level: 0 }), this.updateColumnOrder(), this._columnCheckboxes = [];
let callbackArgs = {
grid: this.grid,
menu: this._menuElm,
allColumns: this.columns,
visibleColumns: this.getVisibleColumns()
};
if (this._gridMenuOptions && !this.runOverrideFunctionWhenExists(this._gridMenuOptions.menuUsabilityOverride, callbackArgs) || typeof e.stopPropagation == "function" && this.onBeforeMenuShow.notify(callbackArgs, e, this).getReturnValue() === !1)
return;
let columnId, columnLabel, excludeCssClass;
for (let i = 0; i < this.columns.length; i++) {
columnId = this.columns[i].id, excludeCssClass = this.columns[i].excludeFromGridMenu ? "hidden" : "";
let colName = this.columns[i].name instanceof HTMLElement ? this.columns[i].name.innerHTML : this.columns[i].name || "", liElm = document.createElement("li");
liElm.className = excludeCssClass, liElm.ariaLabel = colName;
let checkboxElm = document.createElement("input");
checkboxElm.type = "checkbox", checkboxElm.id = `${this._gridUid}-gridmenu-colpicker-${columnId}`, checkboxElm.dataset.columnid = String(this.columns[i].id), liElm.appendChild(checkboxElm), Utils4.isDefined(this.grid.getColumnIndex(this.columns[i].id)) && !this.columns[i].hidden && (checkboxElm.checked = !0), this._columnCheckboxes.push(checkboxElm), columnLabel = this._gridMenuOptions?.headerColumnValueExtractor ? this._gridMenuOptions.headerColumnValueExtractor(this.columns[i], this._gridOptions) : this._defaults.headerColumnValueExtractor(this.columns[i]);
let labelElm = document.createElement("label");
labelElm.htmlFor = `${this._gridUid}-gridmenu-colpicker-${columnId}`, this.grid.applyHtmlCode(labelElm, this.grid.sanitizeHtmlString(Utils4.getHtmlStringOutput(columnLabel || ""))), liElm.appendChild(labelElm), this._listElm.appendChild(liElm);
}
if (this._gridMenuOptions && (!this._gridMenuOptions.hideForceFitButton || !this._gridMenuOptions.hideSyncResizeButton) && this._listElm.appendChild(document.createElement("hr")), !this._gridMenuOptions?.hideForceFitButton) {
let forceFitTitle = this._gridMenuOptions?.forceFitTitle || this._defaults.forceFitTitle, liElm = document.createElement("li");
liElm.ariaLabel = forceFitTitle, liElm.role = "menuitem", this._listElm.appendChild(liElm);
let forceFitCheckboxElm = document.createElement("input");
forceFitCheckboxElm.type = "checkbox", forceFitCheckboxElm.id = `${this._gridUid}-gridmenu-colpicker-forcefit`, forceFitCheckboxElm.dataset.option = "autoresize", liElm.appendChild(forceFitCheckboxElm);
let labelElm = document.createElement("label");
labelElm.htmlFor = `${this._gridUid}-gridmenu-colpicker-forcefit`, labelElm.textContent = forceFitTitle, liElm.appendChild(labelElm), this.grid.getOptions().forceFitColumns && (forceFitCheckboxElm.checked = !0);
}
if (!this._gridMenuOptions?.hideSyncResizeButton) {
let syncResizeTitle = this._gridMenuOptions?.syncResizeTitle || this._defaults.syncResizeTitle, liElm = document.createElement("li");
liElm.ariaLabel = syncResizeTitle, this._listElm.appendChild(liElm);
let syncResizeCheckboxElm = document.createElement("input");
syncResizeCheckboxElm.type = "checkbox", syncResizeCheckboxElm.id = `${this._gridUid}-gridmenu-colpicker-syncresize`, syncResizeCheckboxElm.dataset.option = "syncresize", liElm.appendChild(syncResizeCheckboxElm);
let labelElm = document.createElement("label");
labelElm.htmlFor = `${this._gridUid}-gridmenu-colpicker-syncresize`, labelElm.textContent = syncResizeTitle, liElm.appendChild(labelElm), this.grid.getOptions().syncColumnCellResize && (syncResizeCheckboxElm.checked = !0);
}
let buttonElm = e.target.nodeName === "BUTTON" ? e.target : e.target.querySelector("button");
buttonElm || (buttonElm = e.target.parentElement), this._menuElm.style.display = "block", this._menuElm.style.opacity = "0", this.repositionMenu(e, this._menuElm, buttonElm);
let menuMarginBottom = this._gridMenuOptions?.marginBottom !== void 0 ? this._gridMenuOptions.marginBottom : this._defaults.marginBottom;
this._gridMenuOptions?.height !== void 0 ? this._menuElm.style.height = `${this._gridMenuOptions.height}px` : this._menuElm.style.maxHeight = `${window.innerHeight - targetEvent.clientY - menuMarginBottom}px`, this._menuElm.style.display = "block", this._menuElm.style.opacity = "1", this._menuElm.appendChild(this._listElm), this._isMenuOpen = !0, typeof e.stopPropagation == "function" && this.onAfterMenuShow.notify(callbackArgs, e, this).getReturnValue();
}
getGridUidSelector() {
let gridUid = this.grid.getUID() || "";
return gridUid ? `.${gridUid}` : "";
}
handleBodyMouseDown(e) {
let isMenuClicked = !1;
this._menuElm?.contains(e.target) && (isMenuClicked = !0), isMenuClicked || document.querySelectorAll(`.slick-gridmenu.slick-submenu${this.getGridUidSelector()}`).forEach((subElm) => {
subElm.contains(e.target) && (isMenuClicked = !0);
}), (this._menuElm !== e.target && !isMenuClicked && !e.defaultPrevented && this._isMenuOpen || e.target.className === "close") && this.hideMenu(e);
}
handleMenuItemClick(item, level = 0, e) {
if (item !== "divider" && !item.disabled && !item.divider) {
let command = item.command || "";
if (Utils4.isDefined(command) && !item.commandItems && !item.customItems) {
let callbackArgs = {
grid: this.grid,
command,
item,
allColumns: this.columns,
visibleColumns: this.getVisibleColumns()
};
this.onCommand.notify(callbackArgs, e, this), typeof item.action == "function" && item.action.call(this, e, callbackArgs), !!!this._gridMenuOptions?.leaveOpen && !e.defaultPrevented && this.hideMenu(e), e.preventDefault(), e.stopPropagation();
} else item.commandItems || item.customItems ? this.repositionSubMenu(item, level, e) : this.destroySubMenus();
}
}
hideMenu(e) {
if (this._menuElm) {
let callbackArgs = {
grid: this.grid,
menu: this._menuElm,
allColumns: this.columns,
visibleColumns: this.getVisibleColumns()
};
if (this._isMenuOpen && this.onMenuClose.notify(callbackArgs, e, this).getReturnValue() === !1)
return;
this._isMenuOpen = !1, Utils4.hide(this._menuElm);
}
this.destroySubMenus();
}
/** Update the Titles of each sections (command, commandTitle, ...) */
updateAllTitles(gridMenuOptions) {
this._commandTitleElm && this.grid.applyHtmlCode(this._commandTitleElm, this.grid.sanitizeHtmlString(gridMenuOptions.commandTitle || gridMenuOptions.customTitle || "")), this._columnTitleElm && this.grid.applyHtmlCode(this._columnTitleElm, this.grid.sanitizeHtmlString(gridMenuOptions.columnTitle || ""));
}
addSubMenuTitleWhenExists(item, commandOrOptionMenu) {
if (item !== "divider" && item?.subMenuTitle) {
let subMenuTitleElm = document.createElement("div");
subMenuTitleElm.className = "slick-menu-title", subMenuTitleElm.textContent = item.subMenuTitle;
let subMenuTitleClass = item.subMenuTitleCssClass;
subMenuTitleClass && subMenuTitleElm.classList.add(...Utils4.classNameToList(subMenuTitleClass)), commandOrOptionMenu.appendChild(subMenuTitleElm);
}
}
repositionSubMenu(item, level, e) {
e.target.classList.contains("slick-cell") && this.destroySubMenus();
let subMenuElm = this.createMenu(level + 1, item);
subMenuElm.style.display = "block", document.body.appendChild(subMenuElm), this.repositionMenu(e, subMenuElm);
}
/**
* Reposition the menu drop (up/down) and the side (left/right)
* @param {*} event
*/
repositionMenu(e, menuElm, buttonElm) {
let targetEvent = e.touches ? e.touches[0] : e, isSubMenu = menuElm.classList.contains("slick-submenu"), parentElm = isSubMenu ? e.target.closest(".slick-gridmenu-item") : targetEvent.target, menuIconOffset = Utils4.offset(buttonElm || this._buttonElm), menuWidth = menuElm.offsetWidth, useClickToRepositionMenu = this._gridMenuOptions?.useClickToRepositionMenu !== void 0 ? this._gridMenuOptions.useClickToRepositionMenu : this._defaults.useClickToRepositionMenu, contentMinWidth = this._gridMenuOptions?.contentMinWidth ? this._gridMenuOptions.contentMinWidth : this._defaults.contentMinWidth, currentMenuWidth = contentMinWidth > menuWidth ? contentMinWidth : menuWidth + 5, menuOffsetTop = useClickToRepositionMenu && targetEvent.pageY > 0 ? targetEvent.pageY : menuIconOffset.top + 10, menuOffsetLeft = useClickToRepositionMenu && targetEvent.pageX > 0 ? targetEvent.pageX : menuIconOffset.left + 10;
if (isSubMenu && parentElm) {
let parentOffset = Utils4.offset(parentElm);
menuOffsetLeft = parentOffset?.left ?? 0, menuOffsetTop = parentOffset?.top ?? 0;
let gridPos = this.grid.getGridPosition(), subMenuPosCalc = menuOffsetLeft + Number(menuWidth);
isSubMenu && (subMenuPosCalc += parentElm.clientWidth);
let browserWidth = document.documentElement.clientWidth;
(subMenuPosCalc >= gridPos.width || subMenuPosCalc >= browserWidth ? "left" : "right") === "left" ? (menuElm.classList.remove("dropright"), menuElm.classList.add("dropleft"), menuOffsetLeft -= menuWidth) : (menuElm.classList.remove("dropleft"), menuElm.classList.add("dropright"), isSubMenu && (menuOffsetLeft += parentElm.offsetWidth));
} else
menuOffsetTop += 10, menuOffsetLeft = menuOffsetLeft - currentMenuWidth + 10;
menuElm.style.top = `${menuOffsetTop}px`, menuElm.style.left = `${menuOffsetLeft}px`, contentMinWidth > 0 && (this._menuElm.style.minWidth = `${contentMinWidth}px`);
}
updateColumnOrder() {
let current = this.grid.getColumns().slice(0), ordered = new Array(this.columns.length);
for (let i = 0; i < ordered.length; i++)
this.grid.getColumnIndex(this.columns[i].id) === void 0 ? ordered[i] = this.columns[i] : ordered[i] = current.shift();
this.columns = ordered;
}
updateColumn(e) {
if (e.target.dataset.option === "autoresize") {
let previousVisibleColumns = this.getVisibleColumns(), isChecked = e.target.checked;
this.grid.setOptions({ forceFitColumns: isChecked }), this.grid.setColumns(previousVisibleColumns);
return;
}
if (e.target.dataset.option === "syncresize") {
this.grid.setOptions({ syncColumnCellResize: !!e.target.checked });
return;
}
if (e.target.type === "checkbox") {
let isChecked = e.target.checked, columnId = e.target.dataset.columnid || "", visibleColumns = [];
if (this._columnCheckboxes.forEach((columnCheckbox, idx) => {
columnCheckbox.checked && (this.columns[idx].hidden && (this.columns[idx].hidden = !1), visibleColumns.push(this.columns[idx]));
}), !visibleColumns.length) {
e.target.checked = !0;
return;
}
let callbackArgs = {
columnId,
showing: isChecked,
grid: this.grid,
allColumns: this.columns,
columns: visibleColumns,
visibleColumns: this.getVisibleColumns()
};
this.grid.setColumns(visibleColumns), this.onColumnsChanged.notify(callbackArgs, e, this);
}
}
getAllColumns() {
return this.columns;
}
/** visible columns, we can simply get them directly from the grid */
getVisibleColumns() {
return this.grid.getColumns();
}
/**
* Method that user can pass to override the default behavior.
* In order word, user can choose or an item is (usable/visible/enable) by providing his own logic.
* @param overrideFn: override function callback
* @param args: multiple arguments provided to the override (cell, row, columnDef, dataContext, grid)
*/
runOverrideFunctionWhenExists(overrideFn, args) {
return typeof overrideFn == "function" ? overrideFn.call(this, args) : !0;
}
};
// src/controls/slick.pager.ts
var BindingEventService5 = BindingEventService, SlickGlobalEditorLock2 = SlickGlobalEditorLock, Utils5 = Utils, SlickGridPager = class {
constructor(dataView, grid, selectorOrElm, options) {
this.dataView = dataView;
this.grid = grid;
// --
// public API
// --
// protected props
__publicField(this, "_container");
// the container might be a string, a jQuery object or a native element
__publicField(this, "_statusElm");
__publicField(this, "_bindingEventService");
__publicField(this, "_options");
__publicField(this, "_defaults", {
showAllText: "Showing all {rowCount} rows",
showPageText: "Showing page {pageNum} of {pageCount}",
showCountText: "From {countBegin} to {countEnd} of {rowCount} rows",
showCount: !1,
pagingOptions: [
{ data: 0, name: "All", ariaLabel: "Show All Pages" },
{ data: -1, name: "Auto", ariaLabel: "Auto Page Size" },
{ data: 25, name: "25", ariaLabel: "Show 25 rows per page" },
{ data: 50, name: "50", ariaLabel: "Show 50 rows per page" },
{ data: 100, name: "100", ariaLabel: "Show 100 rows per page" }
],
showPageSizes: !1
});
this._container = this.getContainerElement(selectorOrElm), this._options = Utils5.extend(!0, {}, this._defaults, options), this._bindingEventService = new BindingEventService5(), this.init();
}
init() {
this.constructPagerUI(), this.updatePager(this.dataView.getPagingInfo()), this.dataView.onPagingInfoChanged.subscribe((_e, pagingInfo) => {
this.updatePager(pagingInfo);
});
}
/** Destroy function when element is destroyed */
destroy() {
this.setPageSize(0), this._bindingEventService.unbindAll(), Utils5.emptyElement(this._container);
}
getNavState() {
let cannotLeaveEditMode = !SlickGlobalEditorLock2.commitCurrentEdit(), pagingInfo = this.dataView.getPagingInfo(), lastPage = pagingInfo.totalPages - 1;
return {
canGotoFirst: !cannotLeaveEditMode && pagingInfo.pageSize !== 0 && pagingInfo.pageNum > 0,
canGotoLast: !cannotLeaveEditMode && pagingInfo.pageSize !== 0 && pagingInfo.pageNum !== lastPage,
canGotoPrev: !cannotLeaveEditMode && pagingInfo.pageSize !== 0 && pagingInfo.pageNum > 0,
canGotoNext: !cannotLeaveEditMode && pagingInfo.pageSize !== 0 && pagingInfo.pageNum < lastPage,
pagingInfo
};
}
setPageSize(n) {
this.dataView.setRefreshHints({
isFilterUnchanged: !0
}), this.dataView.setPagingOptions({ pageSize: n });
}
gotoFirst() {
this.getNavState().canGotoFirst && this.dataView.setPagingOptions({ pageNum: 0 });
}
gotoLast() {
let state = this.getNavState();
state.canGotoLast && this.dataView.setPagingOptions({ pageNum: state.pagingInfo.totalPages - 1 });
}
gotoPrev() {
let state = this.getNavState();
state.canGotoPrev && this.dataView.setPagingOptions({ pageNum: state.pagingInfo.pageNum - 1 });
}
gotoNext() {
let state = this.getNavState();
state.canGotoNext && this.dataView.setPagingOptions({ pageNum: state.pagingInfo.pageNum + 1 });
}
getContainerElement(selectorOrElm) {
return typeof selectorOrElm == "string" ? document.querySelector(selectorOrElm) : typeof selectorOrElm == "object" && selectorOrElm[0] ? selectorOrElm[0] : selectorOrElm;
}
constructPagerUI() {
let container = this.getContainerElement(this._container);
if (!container || container.jquery && !container[0])
return;
let navElm = document.createElement("span");
navElm.className = "slick-pager-nav";
let settingsElm = document.createElement("span");
settingsElm.className = "slick-pager-settings", this._statusElm = document.createElement("span"), this._statusElm.className = "slick-pager-status";
let pagerSettingsElm = document.createElement("span");
pagerSettingsElm.className = "slick-pager-settings-expanded", pagerSettingsElm.textContent = "Show: ";
for (let o = 0; o < this._options.pagingOptions.length; o++) {
let p = this._options.pagingOptions[o], anchorElm = document.createElement("a");
anchorElm.textContent = p.name, anchorElm.ariaLabel = p.ariaLabel, anchorElm.dataset.val = String(p.data), pagerSettingsElm.appendChild(anchorElm), this._bindingEventService.bind(anchorElm, "click", (e) => {
let pagesize = e.target.dataset.val;
if (pagesize !== void 0)
if (Number(pagesize) === -1) {
let vp = this.grid.getViewport();
this.setPageSize(vp.bottom - vp.top);
} else
this.setPageSize(parseInt(pagesize));
});
}
pagerSettingsElm.style.display = this._options.showPageSizes ? "block" : "none", settingsElm.appendChild(pagerSettingsElm);
let displayPaginationContainer = document.createElement("span"), displayIconElm = document.createElement("span");
displayPaginationContainer.className = "sgi-container", displayIconElm.ariaLabel = "Show Pagination Options", displayIconElm.role = "button", displayIconElm.className = "sgi sgi-lightbulb", displayPaginationContainer.appendChild(displayIconElm), this._bindingEventService.bind(displayIconElm, "click", () => {
let styleDisplay = pagerSettingsElm.style.display;
pagerSettingsElm.style.display = styleDisplay === "none" ? "inline-flex" : "none";
}), settingsElm.appendChild(displayPaginationContainer), [
{ key: "start", ariaLabel: "First Page", callback: this.gotoFirst },
{ key: "left", ariaLabel: "Previous Page", callback: this.gotoPrev },
{ key: "right", ariaLabel: "Next Page", callback: this.gotoNext },
{ key: "end", ariaLabel: "Last Page", callback: this.gotoLast }
].forEach((pageBtn) => {
let iconElm = document.createElement("span");
iconElm.className = "sgi-container";
let innerIconElm = document.createElement("span");
innerIconElm.role = "button", innerIconElm.ariaLabel = pageBtn.ariaLabel, innerIconElm.className = `sgi sgi-chevron-${pageBtn.key}`, this._bindingEventService.bind(innerIconElm, "click", pageBtn.callback.bind(this)), iconElm.appendChild(innerIconElm), navElm.appendChild(iconElm);
});
let slickPagerElm = document.createElement("div");
slickPagerElm.className = "slick-pager", slickPagerElm.appendChild(navElm), slickPagerElm.appendChild(this._statusElm), slickPagerElm.appendChild(settingsElm), container.appendChild(slickPagerElm);
}
updatePager(pagingInfo) {
if (!this._container || this._container.jquery && !this._container[0])
return;
let state = this.getNavState();
if (this._container.querySelectorAll(".slick-pager-nav span").forEach((pagerIcon) => pagerIcon.classList.remove("sgi-state-disabled")), state.canGotoFirst || this._container.querySelector(".sgi-chevron-start")?.classList.add("sgi-state-disabled"), state.canGotoLast || this._container.querySelector(".sgi-chevron-end")?.classList.add("sgi-state-disabled"), state.canGotoNext || this._container.querySelector(".sgi-chevron-right")?.classList.add("sgi-state-disabled"), state.canGotoPrev || this._container.querySelector(".sgi-chevron-left")?.classList.add("sgi-state-disabled"), pagingInfo.pageSize === 0 ? this._statusElm.textContent = this._options.showAllText.replace("{rowCount}", pagingInfo.totalRows + "").replace("{pageCount}", pagingInfo.totalPages + "") : this._statusElm.textContent = this._options.showPageText.replace("{pageNum}", pagingInfo.pageNum + 1 + "").replace("{pageCount}", pagingInfo.totalPages + ""), this._options.showCount && pagingInfo.pageSize !== 0) {
let pageBegin = pagingInfo.pageNum * pagingInfo.pageSize, currentText = this._statusElm.textContent;
currentText && (currentText += " - "), this._statusElm.textContent = currentText + this._options.showCountText.replace("{rowCount}", String(pagingInfo.totalRows)).replace("{countBegin}", String(pageBegin + 1)).replace("{countEnd}", String(Math.min(pageBegin + pagingInfo.pageSize, pagingInfo.totalRows)));
}
}
};
// src/models/fieldType.enum.ts
var FieldType = {
/** unknown type */
unknown: "unknown",
/** string type */
string: "string",
/** boolean type (true/false) */
boolean: "boolean",
/** integer number type (1,2,99) */
integer: "integer",
/** float number (with decimal) type */
float: "float",
/** number includes Integer and Float */
number: "number",
/** new Date(), javascript Date object */
date: "date",
/** Format: 'YYYY-MM-DD' <=> 2001-02-28 */
dateIso: "dateIso",
/** Format: 'YYYY-MM-DDTHH:mm:ss.SSSZ' <=> 2001-02-28T14:00:00.123Z */
dateUtc: "dateUtc",
/** new Date(), javacript Date Object with Time */
dateTime: "dateTime",
/** Format: 'YYYY-MM-DD HH:mm:ss' <=> 2001-02-28 14:01:01 */
dateTimeIso: "dateTimeIso",
/** Format: 'YYYY-MM-DD hh:mm:ss a' <=> 2001-02-28 11:01:01 pm */
dateTimeIsoAmPm: "dateTimeIsoAmPm",
/** Format: 'YYYY-MM-DD hh:mm:ss A' <=> 2001-02-28 11:01:01 PM */
dateTimeIsoAM_PM: "dateTimeIsoAM_PM",
/** Format: 'YYYY-MM-DD HH:mm' <=> 2001-02-28 14:01 */
dateTimeShortIso: "dateTimeShortIso",
/** Format (Euro): 'DD/MM/YYYY' <=> 28/02/2001 */
dateEuro: "dateEuro",
/** Format (Euro): 'D/M/YY' <=> 28/2/12 */
dateEuroShort: "dateEuroShort",
/** Format (Euro): 'DD/MM/YYYY HH:mm' <=> 28/02/2001 13:01 */
dateTimeShortEuro: "dateTimeShortEuro",
/** Format (Euro): 'DD/MM/YYYY HH:mm:ss' <=> 02/28/2001 13:01:01 */
dateTimeEuro: "dateTimeEuro",
/** Format (Euro): 'DD/MM/YYYY hh:mm:ss a' <=> 28/02/2001 11:01:01 pm */
dateTimeEuroAmPm: "dateTimeEuroAmPm",
/** Format (Euro): 'DD/MM/YYYY hh:mm:ss A' <=> 28/02/2001 11:01:01 PM */
dateTimeEuroAM_PM: "dateTimeEuroAM_PM",
/** Format (Euro): 'D/M/YY H:m:s' <=> 28/2/14 14:1:2 */
dateTimeEuroShort: "dateTimeEuroShort",
/** Format (Euro): 'D/M/YY h:m:s a' <=> 28/2/14 1:2:10 pm */
dateTimeEuroShortAmPm: "dateTimeEuroShortAmPm",
/** Format (Euro): 'D/M/YY h:m:s A' <=> 28/2/14 14:1:1 PM */
dateTimeEuroShortAM_PM: "dateTimeEuroShortAM_PM",
/** Format: 'MM/DD/YYYY' <=> 02/28/2001 */
dateUs: "dateUs",
/** Format: 'M/D/YY' <=> 2/28/12 */
dateUsShort: "dateUsShort",
/** Format: 'MM/DD/YYYY HH:mm' <=> 02/28/2001 13:01 */
dateTimeShortUs: "dateTimeShortUs",
/** Format: 'MM/DD/YYYY HH:mm:ss' <=> 02/28/2001 13:01:01 */
dateTimeUs: "dateTimeUs",
/** Format: 'MM/DD/YYYY hh:mm:ss a' <=> 02/28/2001 11:01:01 pm */
dateTimeUsAmPm: "dateTimeUsAmPm",
/** Format: 'MM/DD/YYYY hh:mm:ss A' <=> 02/28/2001 11:01:01 PM */
dateTimeUsAM_PM: "dateTimeUsAM_PM",
/** Format: 'M/D/YY H:m:s' <=> 2/28/14 14:1:2 */
dateTimeUsShort: "dateTimeUsShort",
/** Format: 'M/D/YY h:m:s a' <=> 2/28/14 1:2:10 pm */
dateTimeUsShortAmPm: "dateTimeUsShortAmPm",
/** Format: 'M/D/YY h:m:s A' <=> 2/28/14 14:1:1 PM */
dateTimeUsShortAM_PM: "dateTimeUsShortAM_PM",
/** complex object with various properties */
object: "object",
/** password text string */
password: "password",
/** alias to string */
text: "text",
/** readonly text string */
readonly: "readonly"
};
// src/models/sortDirectionNumber.enum.ts
var SortDirectionNumber = /* @__PURE__ */ ((SortDirectionNumber2) => (SortDirectionNumber2[SortDirectionNumber2.asc = 1] = "asc", SortDirectionNumber2[SortDirectionNumber2.desc = -1] = "desc", SortDirectionNumber2[SortDirectionNumber2.neutral = 0] = "neutral", SortDirectionNumber2))(SortDirectionNumber || {});
// src/plugins/slick.autotooltips.ts
var Utils6 = Utils, SlickAutoTooltips = class {
/**
* Constructor of the SlickGrid 3rd party plugin, it can optionally receive options
* @param {boolean} [options.enableForCells=true] - Enable tooltip for grid cells
* @param {boolean} [options.enableForHeaderCells=false] - Enable tooltip for header cells
* @param {number} [options.maxToolTipLength=null] - The maximum length for a tooltip
* @param {boolean} [options.replaceExisting=null] - Allow preventing custom tooltips from being overwritten by auto tooltips
*/
constructor(options) {
// --
// public API
__publicField(this, "pluginName", "AutoTooltips");
// --
// protected props
__publicField(this, "_grid");
__publicField(this, "_options");
__publicField(this, "_defaults", {
enableForCells: !0,
enableForHeaderCells: !1,
maxToolTipLength: void 0,
replaceExisting: !0
});
this._options = Utils6.extend(!0, {}, this._defaults, options);
}
/**
* Initialize plugin.
*/
init(grid) {
this._grid = grid, this._options?.enableForCells && this._grid.onMouseEnter.subscribe(this.handleMouseEnter.bind(this)), this._options?.enableForHeaderCells && this._grid.onHeaderMouseEnter.subscribe(this.handleHeaderMouseEnter.bind(this));
}
/**
* Destroy plugin.
*/
destroy() {
this._options?.enableForCells && this._grid.onMouseEnter.unsubscribe(this.handleMouseEnter.bind(this)), this._options?.enableForHeaderCells && this._grid.onHeaderMouseEnter.unsubscribe(this.handleHeaderMouseEnter.bind(this));
}
/**
* Handle mouse entering grid cell to add/remove tooltip.
* @param {SlickEventData} event - The event
*/
handleMouseEnter(event2) {
let cell = this._grid.getCellFromEvent(event2);
if (cell) {
let node = this._grid.getCellNode(cell.row, cell.cell), text;
this._options && node && (!node.title || this._options?.replaceExisting) && (node.clientWidth < node.scrollWidth ? (text = node.textContent?.trim() ?? "", this._options?.maxToolTipLength && text.length > this._options?.maxToolTipLength && (text = text.substring(0, this._options.maxToolTipLength - 3) + "...")) : text = "", node.title = text), node = null;
}
}
/**
* Handle mouse entering header cell to add/remove tooltip.
* @param {SlickEventData} event - The event
* @param {object} args.column - The column definition
*/
handleHeaderMouseEnter(event2, args) {
let column = args.column, node, targetElm = event2.target;
if (targetElm && (node = targetElm.closest(".slick-header-column"), node && !column?.toolTip)) {
let titleVal = targetElm.clientWidth < node.clientWidth ? column?.name ?? "" : "";
node.title = Utils6.getHtmlStringOutput(titleVal, "innerHTML");
}
node = null;
}
};
// src/plugins/slick.cellcopymanager.ts
var keyCode2 = keyCode, SlickEvent5 = SlickEvent, Utils7 = Utils, SlickCellCopyManager = class {
constructor() {
// --
// public API
__publicField(this, "pluginName", "CellCopyManager");
__publicField(this, "onCopyCells", new SlickEvent5("onCopyCells"));
__publicField(this, "onCopyCancelled", new SlickEvent5("onCopyCancelled"));
__publicField(this, "onPasteCells", new SlickEvent5("onPasteCells"));
// --
// protected props
__publicField(this, "_grid");
__publicField(this, "_copiedRanges", null);
}
init(grid) {
this._grid = grid, Utils7.addSlickEventPubSubWhenDefined(grid.getPubSubService(), this), this._grid.onKeyDown.subscribe(this.handleKeyDown.bind(this));
}
destroy() {
this._grid.onKeyDown.unsubscribe(this.handleKeyDown.bind(this));
}
handleKeyDown(e) {
let ranges;
this._grid.getEditorLock().isActive() || (e.which === keyCode2.ESCAPE && this._copiedRanges && (e.preventDefault(), this.clearCopySelection(), this.onCopyCancelled.notify({ ranges: this._copiedRanges }), this._copiedRanges = null), e.which === 67 && (e.ctrlKey || e.metaKey) && (ranges = this._grid.getSelectionModel()?.getSelectedRanges() ?? [], ranges.length !== 0 && (e.preventDefault(), this._copiedRanges = ranges, this.markCopySelection(ranges), this.onCopyCells.notify({ ranges }))), e.which === 86 && (e.ctrlKey || e.metaKey) && this._copiedRanges && (e.preventDefault(), ranges = this._grid.getSelectionModel()?.getSelectedRanges(), this.onPasteCells.notify({ from: this._copiedRanges, to: ranges }), this._grid.getOptions().preserveCopiedSelectionOnPaste || (this.clearCopySelection(), this._copiedRanges = null)));
}
markCopySelection(ranges) {
let columns = this._grid.getColumns(), hash = {};
for (let i = 0; i < ranges.length; i++)
for (let j = ranges[i].fromRow; j <= ranges[i].toRow; j++) {
hash[j] = {};
for (let k = ranges[i].fromCell; k <= ranges[i].toCell; k++)
hash[j][columns[k].id] = "copied";
}
this._grid.setCellCssStyles("copy-manager", hash);
}
clearCopySelection() {
this._grid.removeCellCssStyles("copy-manager");
}
};
// src/plugins/slick.cellexternalcopymanager.ts
var SlickEvent6 = SlickEvent, SlickRange2 = SlickRange, Utils8 = Utils, CLEAR_COPY_SELECTION_DELAY = 2e3, CLIPBOARD_PASTE_DELAY = 100, SlickCellExternalCopyManager = class {
constructor(options) {
// --
// public API
__publicField(this, "pluginName", "CellExternalCopyManager");
__publicField(this, "onCopyCells", new SlickEvent6("onCopyCells"));
__publicField(this, "onCopyCancelled", new SlickEvent6("onCopyCancelled"));
__publicField(this, "onPasteCells", new SlickEvent6("onPasteCells"));
// --
// protected props
__publicField(this, "_grid");
__publicField(this, "_bodyElement");
__publicField(this, "_copiedRanges", null);
__publicField(this, "_clearCopyTI");
__publicField(this, "_copiedCellStyle");
__publicField(this, "_copiedCellStyleLayerKey");
__publicField(this, "_onCopyInit");
__publicField(this, "_onCopySuccess");
__publicField(this, "_options");
__publicField(this, "keyCodes", {
C: 67,
V: 86,
ESC: 27,
INSERT: 45
});
this._options = options || {}, this._copiedCellStyleLayerKey = this._options.copiedCellStyleLayerKey || "copy-manager", this._copiedCellStyle = this._options.copiedCellStyle || "copied", this._bodyElement = this._options.bodyElement || document.body, this._onCopyInit = this._options.onCopyInit || void 0, this._onCopySuccess = this._options.onCopySuccess || void 0;
}
init(grid) {
this._grid = grid, Utils8.addSlickEventPubSubWhenDefined(grid.getPubSubService(), this), this._grid.onKeyDown.subscribe(this.handleKeyDown.bind(this));
let cellSelectionModel = grid.getSelectionModel();
if (!cellSelectionModel)
throw new Error("Selection model is mandatory for this plugin. Please set a selection model on the grid before adding this plugin: grid.setSelectionModel(new Slick.CellSelectionModel())");
cellSelectionModel.onSelectedRangesChanged.subscribe(() => {
this._grid.getEditorLock().isActive() || this._grid.focus();
});
}
destroy() {
this._grid.onKeyDown.unsubscribe(this.handleKeyDown.bind(this));
}
getHeaderValueForColumn(columnDef) {
if (this._options.headerColumnValueExtractor) {
let val = Utils8.getHtmlStringOutput(this._options.headerColumnValueExtractor(columnDef));
if (val)
return val;
}
return Utils8.getHtmlStringOutput(columnDef.name || "");
}
getDataItemValueForColumn(item, columnDef, event2) {
if (typeof this._options.dataItemColumnValueExtractor == "function") {
let val = this._options.dataItemColumnValueExtractor(item, columnDef);
if (val)
return val;
}
let retVal = "";
if (columnDef?.editor) {
let tmpP = document.createElement("p"), editor = new columnDef.editor({
container: tmpP,
// a dummy container
column: columnDef,
event: event2,
position: { top: 0, left: 0 },
// a dummy position required by some editors
grid: this._grid
});
editor.loadValue(item), retVal = editor.serializeValue(), editor.destroy(), tmpP.remove();
} else
retVal = item[columnDef.field || ""];
return retVal;
}
setDataItemValueForColumn(item, columnDef, value) {
if (columnDef.denyPaste)
return null;
if (this._options.dataItemColumnValueSetter)
return this._options.dataItemColumnValueSetter(item, columnDef, value);
if (columnDef.editor) {
let tmpDiv = document.createElement("div"), editor = new columnDef.editor({
container: tmpDiv,
// a dummy container
column: columnDef,
position: { top: 0, left: 0 },
// a dummy position required by some editors
grid: this._grid
});
editor.loadValue(item), editor.applyValue(item, value), editor.destroy(), tmpDiv.remove();
} else
item[columnDef.field] = value;
}
_createTextBox(innerText) {
let scrollPos = document.documentElement.scrollTop || document.body.scrollTop, ta = document.createElement("textarea");
return ta.style.position = "absolute", ta.style.opacity = "0", ta.value = innerText, ta.style.top = `${scrollPos}px`, this._bodyElement.appendChild(ta), ta.select(), ta;
}
_decodeTabularData(grid, ta) {
let columns = grid.getColumns(), clipRows = ta.value.split(/[\n\f\r]/);
clipRows[clipRows.length - 1] === "" && clipRows.pop();
let j = 0, clippedRange = [];
this._bodyElement.removeChild(ta);
for (let i = 0; i < clipRows.length; i++)
clipRows[i] !== "" ? clippedRange[j++] = clipRows[i].split(" ") : clippedRange[j++] = [""];
let selectedCell = grid.getActiveCell(), ranges = grid.getSelectionModel()?.getSelectedRanges(), selectedRange = ranges && ranges.length ? ranges[0] : null, activeRow, activeCell;
if (selectedRange)
activeRow = selectedRange.fromRow, activeCell = selectedRange.fromCell;
else if (selectedCell)
activeRow = selectedCell.row, activeCell = selectedCell.cell;
else
return;
let oneCellToMultiple = !1, destH = clippedRange.length, destW = clippedRange.length ? clippedRange[0].length : 0;
clippedRange.length === 1 && clippedRange[0].length === 1 && selectedRange && (oneCellToMultiple = !0, destH = selectedRange.toRow - selectedRange.fromRow + 1, destW = selectedRange.toCell - selectedRange.fromCell + 1);
let availableRows = grid.getData().length - (activeRow || 0), addRows = 0;
if (availableRows < destH && typeof this._options.newRowCreator == "function") {
let d = grid.getData();
for (addRows = 1; addRows <= destH - availableRows; addRows++)
d.push({});
grid.setData(d), grid.render();
}
let overflowsBottomOfGrid = (activeRow || 0) + destH > grid.getDataLength();
if (this._options.newRowCreator && overflowsBottomOfGrid) {
let newRowsNeeded = (activeRow || 0) + destH - grid.getDataLength();
this._options.newRowCreator(newRowsNeeded);
}
let clipCommand = {
isClipboardCommand: !0,
clippedRange,
oldValues: [],
cellExternalCopyManager: this,
_options: this._options,
setDataItemValueForColumn: this.setDataItemValueForColumn.bind(this),
markCopySelection: this.markCopySelection.bind(this),
oneCellToMultiple,
activeRow,
activeCell,
destH,
destW,
maxDestY: grid.getDataLength(),
maxDestX: grid.getColumns().length,
h: 0,
w: 0,
execute: () => {
clipCommand.h = 0;
for (let y = 0; y < clipCommand.destH; y++) {
clipCommand.oldValues[y] = [], clipCommand.w = 0, clipCommand.h++;
let xOffset = 0;
for (let x = 0; x < clipCommand.destW; x++) {
let desty = activeRow + y, destx = activeCell + x, column = columns[destx];
if (column.hidden) {
clipCommand.destW++, xOffset++;
continue;
}
if (clipCommand.w++, desty < clipCommand.maxDestY && destx < clipCommand.maxDestX) {
let dt = grid.getDataItem(desty);
clipCommand.oldValues[y][x - xOffset] = dt[column.field], oneCellToMultiple ? clipCommand.setDataItemValueForColumn(dt, column, clippedRange[0][0]) : clipCommand.setDataItemValueForColumn(dt, column, clippedRange[y] ? clippedRange[y][x - xOffset] : ""), grid.updateCell(desty, destx), grid.onCellChange.notify({
row: desty,
cell: destx,
item: dt,
grid,
column: {}
});
}
}
}
let bRange = new SlickRange2(
activeRow,
activeCell,
activeRow + clipCommand.h - 1,
activeCell + clipCommand.w - 1
);
this.markCopySelection([bRange]), grid.getSelectionModel()?.setSelectedRanges([bRange]), this.onPasteCells.notify({ ranges: [bRange] });
},
undo: () => {
for (let y = 0; y < clipCommand.destH; y++)
for (let x = 0; x < clipCommand.destW; x++) {
let desty = activeRow + y, destx = activeCell + x;
if (desty < clipCommand.maxDestY && destx < clipCommand.maxDestX) {
let dt = grid.getDataItem(desty);
oneCellToMultiple ? clipCommand.setDataItemValueForColumn(dt, columns[destx], clipCommand.oldValues[0][0]) : clipCommand.setDataItemValueForColumn(dt, columns[destx], clipCommand.oldValues[y][x]), grid.updateCell(desty, destx), grid.onCellChange.notify({
row: desty,
cell: destx,
item: dt,
grid,
column: {}
});
}
}
let bRange = new SlickRange2(
activeRow,
activeCell,
activeRow + clipCommand.h - 1,
activeCell + clipCommand.w - 1
);
if (this.markCopySelection([bRange]), grid.getSelectionModel()?.setSelectedRanges([bRange]), typeof this._options.onPasteCells == "function" && this.onPasteCells.notify({ ranges: [bRange] }), addRows > 1) {
let d = grid.getData();
for (; addRows > 1; addRows--)
d.splice(d.length - 1, 1);
grid.setData(d), grid.render();
}
}
};
typeof this._options.clipboardCommandHandler == "function" ? this._options.clipboardCommandHandler(clipCommand) : clipCommand.execute();
}
handleKeyDown(e) {
let ranges;
if (!this._grid.getEditorLock().isActive() || this._grid.getOptions().autoEdit) {
if (e.which === this.keyCodes.ESC && this._copiedRanges && (e.preventDefault(), this.clearCopySelection(), this.onCopyCancelled.notify({ ranges: this._copiedRanges }), this._copiedRanges = null), (e.which === this.keyCodes.C || e.which === this.keyCodes.INSERT) && (e.ctrlKey || e.metaKey) && !e.shiftKey && (typeof this._onCopyInit == "function" && this._onCopyInit.call(this), ranges = this._grid.getSelectionModel()?.getSelectedRanges() ?? [], ranges.length !== 0)) {
this._copiedRanges = ranges, this.markCopySelection(ranges), this.onCopyCells.notify({ ranges });
let columns = this._grid.getColumns(), clipText = "";
for (let rg = 0; rg < ranges.length; rg++) {
let range = ranges[rg], clipTextRows = [];
for (let i = range.fromRow; i < range.toRow + 1; i++) {
let clipTextCells = [], dt = this._grid.getDataItem(i);
if (clipTextRows.length === 0 && this._options.includeHeaderWhenCopying) {
let clipTextHeaders = [];
for (let j = range.fromCell; j < range.toCell + 1; j++)
(columns[j].name instanceof HTMLElement ? columns[j].name.innerHTML : columns[j].name).length > 0 && !columns[j].hidden && clipTextHeaders.push(this.getHeaderValueForColumn(columns[j]) || "");
clipTextRows.push(clipTextHeaders.join(" "));
}
for (let j = range.fromCell; j < range.toCell + 1; j++)
(columns[j].name instanceof HTMLElement ? columns[j].name.innerHTML : columns[j].name).length > 0 && !columns[j].hidden && clipTextCells.push(this.getDataItemValueForColumn(dt, columns[j], e));
clipTextRows.push(clipTextCells.join(" "));
}
clipText += clipTextRows.join(`\r
`) + `\r
`;
}
if (window.clipboardData)
return window.clipboardData.setData("Text", clipText), !0;
{
let focusEl = document.activeElement, ta = this._createTextBox(clipText);
if (ta.focus(), window.setTimeout(() => {
this._bodyElement.removeChild(ta), focusEl ? focusEl.focus() : console.log("No element to restore focus to after copy?");
}, this._options?.clipboardPasteDelay ?? CLIPBOARD_PASTE_DELAY), typeof this._onCopySuccess == "function") {
let rowCount = 0;
ranges.length === 1 ? rowCount = ranges[0].toRow + 1 - ranges[0].fromRow : rowCount = ranges.length, this._onCopySuccess(rowCount);
}
return !1;
}
}
if (!this._options.readOnlyMode && (e.which === this.keyCodes.V && (e.ctrlKey || e.metaKey) && !e.shiftKey || e.which === this.keyCodes.INSERT && e.shiftKey && !e.ctrlKey)) {
let focusEl = document.activeElement, ta = this._createTextBox("");
return window.setTimeout(() => {
this._decodeTabularData(this._grid, ta), focusEl?.focus();
}, this._options?.clipboardPasteDelay ?? CLIPBOARD_PASTE_DELAY), !1;
}
}
}
markCopySelection(ranges) {
this.clearCopySelection();
let columns = this._grid.getColumns(), hash = {};
for (let i = 0; i < ranges.length; i++)
for (let j = ranges[i].fromRow; j <= ranges[i].toRow; j++) {
hash[j] = {};
for (let k = ranges[i].fromCell; k <= ranges[i].toCell && k < columns.length; k++)
hash[j][columns[k].id] = this._copiedCellStyle;
}
this._grid.setCellCssStyles(this._copiedCellStyleLayerKey, hash), window.clearTimeout(this._clearCopyTI), this._clearCopyTI = window.setTimeout(() => {
this.clearCopySelection();
}, this._options?.clearCopySelectionDelay || CLEAR_COPY_SELECTION_DELAY);
}
clearCopySelection() {
this._grid.removeCellCssStyles(this._copiedCellStyleLayerKey);
}
setIncludeHeaderWhenCopying(includeHeaderWhenCopying) {
this._options.includeHeaderWhenCopying = includeHeaderWhenCopying;
}
};
// src/plugins/slick.cellmenu.ts
var BindingEventService6 = BindingEventService, SlickEvent7 = SlickEvent, SlickEventData2 = SlickEventData, EventHandler2 = SlickEventHandler, Utils9 = Utils, SlickCellMenu = class {
constructor(optionProperties) {
// --
// public API
__publicField(this, "pluginName", "CellMenu");
__publicField(this, "onAfterMenuShow", new SlickEvent7("onAfterMenuShow"));
__publicField(this, "onBeforeMenuShow", new SlickEvent7("onBeforeMenuShow"));
__publicField(this, "onBeforeMenuClose", new SlickEvent7("onBeforeMenuClose"));
__publicField(this, "onCommand", new SlickEvent7("onCommand"));
__publicField(this, "onOptionSelected", new SlickEvent7("onOptionSelected"));
// --
// protected props
__publicField(this, "_bindingEventService", new BindingEventService6());
__publicField(this, "_cellMenuProperties");
__publicField(this, "_currentCell", -1);
__publicField(this, "_currentRow", -1);
__publicField(this, "_grid");
__publicField(this, "_gridOptions");
__publicField(this, "_gridUid", "");
__publicField(this, "_handler", new EventHandler2());
__publicField(this, "_commandTitleElm");
__publicField(this, "_optionTitleElm");
__publicField(this, "_lastMenuTypeClicked", "");
__publicField(this, "_menuElm");
__publicField(this, "_subMenuParentId", "");
__publicField(this, "_defaults", {
autoAdjustDrop: !0,
// dropup/dropdown
autoAlignSide: !0,
// left/right
autoAdjustDropOffset: 0,
autoAlignSideOffset: 0,
hideMenuOnScroll: !0,
maxHeight: "none",
width: "auto",
subMenuOpenByEvent: "mouseover"
});
this._cellMenuProperties = Utils9.extend({}, this._defaults, optionProperties);
}
init(grid) {
this._grid = grid, this._gridOptions = grid.getOptions(), Utils9.addSlickEventPubSubWhenDefined(grid.getPubSubService(), this), this._gridUid = grid?.getUID() || "", this._handler.subscribe(this._grid.onClick, this.handleCellClick.bind(this)), this._cellMenuProperties.hideMenuOnScroll && this._handler.subscribe(this._grid.onScroll, this.closeMenu.bind(this));
}
setOptions(newOptions) {
this._cellMenuProperties = Utils9.extend({}, this._cellMenuProperties, newOptions);
}
destroy() {
this.onAfterMenuShow.unsubscribe(), this.onBeforeMenuShow.unsubscribe(), this.onBeforeMenuClose.unsubscribe(), this.onCommand.unsubscribe(), this.onOptionSelected.unsubscribe(), this._handler.unsubscribeAll(), this._bindingEventService.unbindAll(), this._menuElm?.remove(), this._commandTitleElm = null, this._optionTitleElm = null, this._menuElm = null;
}
createParentMenu(e) {
let cell = this._grid.getCellFromEvent(e);
this._currentCell = cell?.cell ?? 0, this._currentRow = cell?.row ?? 0;
let columnDef = this._grid.getColumns()[this._currentCell], commandItems = this._cellMenuProperties.commandItems || [], optionItems = this._cellMenuProperties.optionItems || [];
if (!(!columnDef || !columnDef.cellMenu || !commandItems.length && !optionItems.length) && (this.closeMenu(), this.onBeforeMenuShow.notify({
cell: this._currentCell,
row: this._currentRow,
grid: this._grid
}, e, this).getReturnValue() !== !1 && (this._menuElm = this.createMenu(commandItems, optionItems), this._menuElm.style.top = `${e.pageY + 5}px`, this._menuElm.style.left = `${e.pageX}px`, this._menuElm.style.display = "block", document.body.appendChild(this._menuElm), this.onAfterMenuShow.notify({
cell: this._currentCell,
row: this._currentRow,
grid: this._grid
}, e, this).getReturnValue() !== !1)))
return this._menuElm;
}
/**
* Create parent menu or sub-menu(s), a parent menu will start at level 0 while sub-menu(s) will be incremented
* @param commandItems - array of optional commands or dividers
* @param optionItems - array of optional options or dividers
* @param level - menu level
* @param item - command, option or divider
* @returns menu DOM element
*/
createMenu(commandItems, optionItems, level = 0, item) {
let columnDef = this._grid.getColumns()[this._currentCell], dataContext = this._grid.getDataItem(this._currentRow), maxHeight = isNaN(this._cellMenuProperties.maxHeight) ? this._cellMenuProperties.maxHeight : `${this._cellMenuProperties.maxHeight ?? 0}px`, width = isNaN(this._cellMenuProperties.width) ? this._cellMenuProperties.width : `${this._cellMenuProperties.maxWidth ?? 0}px`, subMenuCommand = item?.command, subMenuId = level === 1 && subMenuCommand ? subMenuCommand.replaceAll(" ", "") : "";
subMenuId && (this._subMenuParentId = subMenuId), level > 1 && (subMenuId = this._subMenuParentId);
let menuClasses = `slick-cell-menu slick-menu-level-${level} ${this._gridUid}`, bodyMenuElm = document.body.querySelector(`.slick-cell-menu.slick-menu-level-${level}${this.getGridUidSelector()}`);
if (bodyMenuElm) {
if (bodyMenuElm.dataset.subMenuParent === subMenuId)
return bodyMenuElm;
this.destroySubMenus();
}
let menuElm = document.createElement("div");
menuElm.className = menuClasses, level > 0 && (menuElm.classList.add("slick-submenu"), subMenuId && (menuElm.dataset.subMenuParent = subMenuId)), menuElm.ariaLabel = level > 1 ? "SubMenu" : "Cell Menu", menuElm.role = "menu", width && (menuElm.style.width = width), maxHeight && (menuElm.style.maxHeight = maxHeight), menuElm.style.display = "none";
let closeButtonElm = null;
if (level === 0) {
closeButtonElm = document.createElement("button"), closeButtonElm.type = "button", closeButtonElm.className = "close", closeButtonElm.dataset.dismiss = "slick-cell-menu", closeButtonElm.ariaLabel = "Close";
let spanCloseElm = document.createElement("span");
spanCloseElm.className = "close", spanCloseElm.ariaHidden = "true", spanCloseElm.textContent = "\xD7", closeButtonElm.appendChild(spanCloseElm);
}
if (!this._cellMenuProperties.hideOptionSection && optionItems.length > 0) {
let optionMenuElm = document.createElement("div");
optionMenuElm.className = "slick-cell-menu-option-list", optionMenuElm.role = "menu", item && level > 0 && this.addSubMenuTitleWhenExists(item, optionMenuElm), closeButtonElm && !this._cellMenuProperties.hideCloseButton && (this._bindingEventService.bind(closeButtonElm, "click", this.handleCloseButtonClicked.bind(this)), menuElm.appendChild(closeButtonElm)), menuElm.appendChild(optionMenuElm), this.populateCommandOrOptionItems(
"option",
this._cellMenuProperties,
optionMenuElm,
optionItems,
{ cell: this._currentCell, row: this._currentRow, column: columnDef, dataContext, grid: this._grid, level }
);
}
if (!this._cellMenuProperties.hideCommandSection && commandItems.length > 0) {
let commandMenuElm = document.createElement("div");
commandMenuElm.className = "slick-cell-menu-command-list", commandMenuElm.role = "menu", item && level > 0 && this.addSubMenuTitleWhenExists(item, commandMenuElm), closeButtonElm && !this._cellMenuProperties.hideCloseButton && (optionItems.length === 0 || this._cellMenuProperties.hideOptionSection) && (this._bindingEventService.bind(closeButtonElm, "click", this.handleCloseButtonClicked.bind(this)), menuElm.appendChild(closeButtonElm)), menuElm.appendChild(commandMenuElm), this.populateCommandOrOptionItems(
"command",
this._cellMenuProperties,
commandMenuElm,
commandItems,
{ cell: this._currentCell, row: this._currentRow, column: columnDef, dataContext, grid: this._grid, level }
);
}
return level++, menuElm;
}
addSubMenuTitleWhenExists(item, commandOrOptionMenu) {
if (item !== "divider" && item?.subMenuTitle) {
let subMenuTitleElm = document.createElement("div");
subMenuTitleElm.className = "slick-menu-title", subMenuTitleElm.textContent = item.subMenuTitle;
let subMenuTitleClass = item.subMenuTitleCssClass;
subMenuTitleClass && subMenuTitleElm.classList.add(...Utils9.classNameToList(subMenuTitleClass)), commandOrOptionMenu.appendChild(subMenuTitleElm);
}
}
handleCloseButtonClicked(e) {
e.defaultPrevented || this.closeMenu(e);
}
/** Close and destroy Cell Menu */
closeMenu(e, args) {
if (this._menuElm) {
if (this.onBeforeMenuClose.notify({
cell: args?.cell ?? 0,
row: args?.row ?? 0,
grid: this._grid
}, e, this).getReturnValue() === !1)
return;
this._menuElm.remove(), this._menuElm = null;
}
this.destroySubMenus();
}
/** Destroy all parent menus and any sub-menus */
destroyAllMenus() {
this.destroySubMenus(), this._bindingEventService.unbindAll("parent-menu"), document.querySelectorAll(`.slick-cell-menu${this.getGridUidSelector()}`).forEach((subElm) => subElm.remove());
}
/** Close and destroy all previously opened sub-menus */
destroySubMenus() {
this._bindingEventService.unbindAll("sub-menu"), document.querySelectorAll(`.slick-cell-menu.slick-submenu${this.getGridUidSelector()}`).forEach((subElm) => subElm.remove());
}
repositionSubMenu(item, type, level, e) {
(e.target.classList.contains("slick-cell") || this._lastMenuTypeClicked !== type) && this.destroySubMenus();
let subMenuElm = this.createMenu(item?.commandItems || [], item?.optionItems || [], level + 1, item);
subMenuElm.style.display = "block", document.body.appendChild(subMenuElm), this.repositionMenu(e, subMenuElm);
}
/**
* Reposition the menu drop (up/down) and the side (left/right)
* @param {*} event
*/
repositionMenu(e, menuElm) {
let isSubMenu = menuElm.classList.contains("slick-submenu"), parentElm = isSubMenu ? e.target.closest(".slick-cell-menu-item") : e.target.closest(".slick-cell");
if (menuElm && parentElm) {
let parentOffset = Utils9.offset(parentElm), menuOffsetLeft = parentElm ? parentOffset?.left ?? 0 : e?.pageX ?? 0, menuOffsetTop = parentElm ? parentOffset?.top ?? 0 : e?.pageY ?? 0, parentCellWidth = parentElm?.offsetWidth || 0, menuHeight = menuElm?.offsetHeight ?? 0, menuWidth = Number(menuElm?.offsetWidth ?? this._cellMenuProperties.width ?? 0), rowHeight = this._gridOptions.rowHeight, dropOffset = Number(this._cellMenuProperties.autoAdjustDropOffset || 0), sideOffset = Number(this._cellMenuProperties.autoAlignSideOffset || 0);
if (this._cellMenuProperties.autoAdjustDrop) {
let spaceBottom = Utils9.calculateAvailableSpace(parentElm).bottom, spaceTop = Utils9.calculateAvailableSpace(parentElm).top, spaceBottomRemaining = spaceBottom + dropOffset - rowHeight, spaceTopRemaining = spaceTop - dropOffset + rowHeight;
(spaceBottomRemaining < menuHeight && spaceTopRemaining > spaceBottomRemaining ? "top" : "bottom") === "top" ? (menuElm.classList.remove("dropdown"), menuElm.classList.add("dropup"), isSubMenu ? menuOffsetTop -= menuHeight - dropOffset - parentElm.clientHeight : menuOffsetTop -= menuHeight - dropOffset) : (menuElm.classList.remove("dropup"), menuElm.classList.add("dropdown"), isSubMenu ? menuOffsetTop += dropOffset : menuOffsetTop += rowHeight + dropOffset);
}
if (this._cellMenuProperties.autoAlignSide) {
let gridPos = this._grid.getGridPosition(), subMenuPosCalc = menuOffsetLeft + Number(menuWidth);
isSubMenu && (subMenuPosCalc += parentElm.clientWidth);
let browserWidth = document.documentElement.clientWidth;
(subMenuPosCalc >= gridPos.width || subMenuPosCalc >= browserWidth ? "left" : "right") === "left" ? (menuElm.classList.remove("dropright"), menuElm.classList.add("dropleft"), isSubMenu ? menuOffsetLeft -= menuWidth - sideOffset : menuOffsetLeft -= menuWidth - parentCellWidth - sideOffset) : (menuElm.classList.remove("dropleft"), menuElm.classList.add("dropright"), isSubMenu ? menuOffsetLeft += sideOffset + parentElm.offsetWidth : menuOffsetLeft += sideOffset);
}
menuElm.style.top = `${menuOffsetTop}px`, menuElm.style.left = `${menuOffsetLeft}px`;
}
}
getGridUidSelector() {
let gridUid = this._grid.getUID() || "";
return gridUid ? `.${gridUid}` : "";
}
handleCellClick(evt, args) {
this.destroyAllMenus();
let e = evt instanceof SlickEventData2 ? evt.getNativeEvent() : evt, cell = this._grid.getCellFromEvent(e);
if (cell) {
let dataContext = this._grid.getDataItem(cell.row), columnDef = this._grid.getColumns()[cell.cell];
if (columnDef?.cellMenu && e.preventDefault(), this._cellMenuProperties = Utils9.extend({}, this._cellMenuProperties, columnDef.cellMenu), args = args || {}, args.column = columnDef, args.dataContext = dataContext, args.grid = this._grid, !this.runOverrideFunctionWhenExists(this._cellMenuProperties.menuUsabilityOverride, args))
return;
this._menuElm = this.createParentMenu(e), this._menuElm && (this.repositionMenu(e, this._menuElm), this._menuElm.setAttribute("aria-expanded", "true"), this._menuElm.style.display = "block"), this._bindingEventService.bind(document.body, "mousedown", this.handleBodyMouseDown.bind(this));
}
}
/** When users click outside the Cell Menu, we will typically close the Cell Menu (and any sub-menus) */
handleBodyMouseDown(e) {
let isMenuClicked = !1;
this._menuElm?.contains(e.target) && (isMenuClicked = !0), isMenuClicked || document.querySelectorAll(`.slick-cell-menu.slick-submenu${this.getGridUidSelector()}`).forEach((subElm) => {
subElm.contains(e.target) && (isMenuClicked = !0);
}), this._menuElm !== e.target && !isMenuClicked && !e.defaultPrevented && this.closeMenu(e, { cell: this._currentCell, row: this._currentRow, grid: this._grid });
}
/** Build the Command Items section. */
populateCommandOrOptionItems(itemType, cellMenu, commandOrOptionMenuElm, commandOrOptionItems, args) {
if (!args || !commandOrOptionItems || !cellMenu)
return;
let level = args?.level || 0, isSubMenu = level > 0;
cellMenu?.[`${itemType}Title`] && !isSubMenu && (this[`_${itemType}TitleElm`] = document.createElement("div"), this[`_${itemType}TitleElm`].className = "slick-menu-title", this[`_${itemType}TitleElm`].textContent = cellMenu[`${itemType}Title`], commandOrOptionMenuElm.appendChild(this[`_${itemType}TitleElm`]));
for (let i = 0, ln = commandOrOptionItems.length; i < ln; i++) {
let addClickListener = !0, item = commandOrOptionItems[i], isItemVisible = this.runOverrideFunctionWhenExists(item.itemVisibilityOverride, args), isItemUsable = this.runOverrideFunctionWhenExists(item.itemUsabilityOverride, args);
if (!isItemVisible)
continue;
Object.prototype.hasOwnProperty.call(item, "itemUsabilityOverride") && (item.disabled = !isItemUsable);
let liElm = document.createElement("div");
liElm.className = "slick-cell-menu-item", liElm.role = "menuitem", (item.divider || item === "divider") && (liElm.classList.add("slick-cell-menu-item-divider"), addClickListener = !1), (item.disabled || !isItemUsable) && liElm.classList.add("slick-cell-menu-item-disabled"), item.hidden && liElm.classList.add("slick-cell-menu-item-hidden"), item.cssClass && liElm.classList.add(...Utils9.classNameToList(item.cssClass)), item.tooltip && (liElm.title = item.tooltip || "");
let iconElm = document.createElement("div");
iconElm.className = "slick-cell-menu-icon", liElm.appendChild(iconElm), item.iconCssClass && iconElm.classList.add(...Utils9.classNameToList(item.iconCssClass)), item.iconImage && (iconElm.style.backgroundImage = `url(${item.iconImage})`);
let textElm = document.createElement("span");
if (textElm.className = "slick-cell-menu-content", textElm.textContent = item.title || "", liElm.appendChild(textElm), item.textCssClass && textElm.classList.add(...Utils9.classNameToList(item.textCssClass)), commandOrOptionMenuElm.appendChild(liElm), addClickListener) {
let eventGroup = isSubMenu ? "sub-menu" : "parent-menu";
this._bindingEventService.bind(liElm, "click", this.handleMenuItemClick.bind(this, item, itemType, level), void 0, eventGroup);
}
if (this._cellMenuProperties.subMenuOpenByEvent === "mouseover" && this._bindingEventService.bind(liElm, "mouseover", (e) => {
item.commandItems || item.optionItems ? (this.repositionSubMenu(item, itemType, level, e), this._lastMenuTypeClicked = itemType) : isSubMenu || this.destroySubMenus();
}), item.commandItems || item.optionItems) {
let chevronElm = document.createElement("span");
chevronElm.className = "sub-item-chevron", this._cellMenuProperties.subItemChevronClass ? chevronElm.classList.add(...Utils9.classNameToList(this._cellMenuProperties.subItemChevronClass)) : chevronElm.textContent = "\u2B9E", liElm.classList.add("slick-submenu-item"), liElm.appendChild(chevronElm);
continue;
}
}
}
handleMenuItemClick(item, type, level = 0, e) {
if (item?.[type] !== void 0 && item !== "divider" && !item.disabled && !item.divider && this._currentCell !== void 0 && this._currentRow !== void 0) {
if (type === "option" && !this._grid.getEditorLock().commitCurrentEdit())
return;
let optionOrCommand = item[type] !== void 0 ? item[type] : "", row = this._currentRow, cell = this._currentCell, columnDef = this._grid.getColumns()[cell], dataContext = this._grid.getDataItem(row);
if (optionOrCommand !== void 0 && !item[`${type}Items`]) {
let callbackArgs = {
cell,
row,
grid: this._grid,
[type]: optionOrCommand,
item,
column: columnDef,
dataContext
};
this[type === "command" ? "onCommand" : "onOptionSelected"].notify(callbackArgs, e, this), typeof item.action == "function" && item.action.call(this, e, callbackArgs), e.defaultPrevented || this.closeMenu(e, { cell, row, grid: this._grid });
} else item.commandItems || item.optionItems ? this.repositionSubMenu(item, type, level, e) : this.destroySubMenus();
this._lastMenuTypeClicked = type;
}
}
/**
* Method that user can pass to override the default behavior.
* In order word, user can choose or an item is (usable/visible/enable) by providing his own logic.
* @param overrideFn: override function callback
* @param args: multiple arguments provided to the override (cell, row, columnDef, dataContext, grid)
*/
runOverrideFunctionWhenExists(overrideFn, args) {
return typeof overrideFn == "function" ? overrideFn.call(this, args) : !0;
}
};
// src/plugins/slick.cellrangedecorator.ts
var Utils10 = Utils, SlickCellRangeDecorator = class {
constructor(grid, options) {
this.grid = grid;
// --
// public API
__publicField(this, "pluginName", "CellRangeDecorator");
// --
// protected props
__publicField(this, "_options");
__publicField(this, "_elem");
__publicField(this, "_defaults", {
selectionCssClass: "slick-range-decorator",
selectionCss: {
zIndex: "9999",
border: "2px dashed red"
},
offset: { top: -1, left: -1, height: -2, width: -2 }
});
this._options = Utils10.extend(!0, {}, this._defaults, options);
}
destroy() {
this.hide();
}
init() {
}
hide() {
this._elem?.remove(), this._elem = null;
}
show(range) {
if (!this._elem) {
this._elem = document.createElement("div"), this._elem.className = this._options.selectionCssClass, Object.keys(this._options.selectionCss).forEach((cssStyleKey) => {
this._elem.style[cssStyleKey] = this._options.selectionCss[cssStyleKey];
}), this._elem.style.position = "absolute";
let canvasNode = this.grid.getActiveCanvasNode();
canvasNode && canvasNode.appendChild(this._elem);
}
let from = this.grid.getCellNodeBox(range.fromRow, range.fromCell), to = this.grid.getCellNodeBox(range.toRow, range.toCell);
return from && to && this._options?.offset && (this._elem.style.top = `${from.top + this._options.offset.top}px`, this._elem.style.left = `${from.left + this._options.offset.left}px`, this._elem.style.height = `${to.bottom - from.top + this._options.offset.height}px`, this._elem.style.width = `${to.right - from.left + this._options.offset.width}px`), this._elem;
}
};
// src/slick.interactions.ts
var Utils11 = Utils;
function Draggable(options) {
let { containerElement } = options, { onDragInit, onDragStart, onDrag, onDragEnd, preventDragFromKeys } = options, element, startX, startY, deltaX, deltaY, dragStarted;
containerElement || (containerElement = document.body);
let originaldd = {
dragSource: containerElement,
dragHandle: null
};
function init() {
containerElement && (containerElement.addEventListener("mousedown", userPressed), containerElement.addEventListener("touchstart", userPressed));
}
function executeDragCallbackWhenDefined(callback, evt, dd) {
if (typeof callback == "function")
return callback(evt, dd);
}
function destroy() {
containerElement && (containerElement.removeEventListener("mousedown", userPressed), containerElement.removeEventListener("touchstart", userPressed));
}
function preventDrag(event2) {
let eventPrevented = !1;
return preventDragFromKeys && preventDragFromKeys.forEach((key) => {
event2[key] && (eventPrevented = !0);
}), eventPrevented;
}
function userPressed(event2) {
if (!preventDrag(event2)) {
element = event2.target;
let targetEvent = event2?.touches?.[0] ?? event2, { target } = targetEvent;
if (!options.allowDragFrom || options.allowDragFrom && element.matches(options.allowDragFrom) || options.allowDragFromClosest && element.closest(options.allowDragFromClosest)) {
originaldd.dragHandle = element;
let winScrollPos = Utils11.windowScrollPosition();
startX = winScrollPos.left + targetEvent.clientX, startY = winScrollPos.top + targetEvent.clientY, deltaX = targetEvent.clientX - targetEvent.clientX, deltaY = targetEvent.clientY - targetEvent.clientY, originaldd = Object.assign(originaldd, { deltaX, deltaY, startX, startY, target }), executeDragCallbackWhenDefined(onDragInit, event2, originaldd) !== !1 && (document.body.addEventListener("mousemove", userMoved), document.body.addEventListener("touchmove", userMoved), document.body.addEventListener("mouseup", userReleased), document.body.addEventListener("touchend", userReleased), document.body.addEventListener("touchcancel", userReleased));
}
}
}
function userMoved(event2) {
if (!preventDrag(event2)) {
let targetEvent = event2?.touches?.[0] ?? event2;
deltaX = targetEvent.clientX - startX, deltaY = targetEvent.clientY - startY;
let { target } = targetEvent;
dragStarted || (originaldd = Object.assign(originaldd, { deltaX, deltaY, startX, startY, target }), executeDragCallbackWhenDefined(onDragStart, event2, originaldd), dragStarted = !0), originaldd = Object.assign(originaldd, { deltaX, deltaY, startX, startY, target }), executeDragCallbackWhenDefined(onDrag, event2, originaldd);
}
}
function userReleased(event2) {
if (document.body.removeEventListener("mousemove", userMoved), document.body.removeEventListener("touchmove", userMoved), document.body.removeEventListener("mouseup", userReleased), document.body.removeEventListener("touchend", userReleased), document.body.removeEventListener("touchcancel", userReleased), dragStarted) {
let { target } = event2;
originaldd = Object.assign(originaldd, { target }), executeDragCallbackWhenDefined(onDragEnd, event2, originaldd), dragStarted = !1;
}
}
return init(), { destroy };
}
function MouseWheel(options) {
let { element, onMouseWheel } = options;
function destroy() {
element.removeEventListener("wheel", wheelHandler), element.removeEventListener("mousewheel", wheelHandler);
}
function init() {
element.addEventListener("wheel", wheelHandler), element.addEventListener("mousewheel", wheelHandler);
}
function wheelHandler(event2) {
let orgEvent = event2 || window.event, delta = 0, deltaX = 0, deltaY = 0;
orgEvent.wheelDelta && (delta = orgEvent.wheelDelta / 120), orgEvent.detail && (delta = -orgEvent.detail / 3), deltaY = delta, orgEvent.axis !== void 0 && orgEvent.axis === orgEvent.HORIZONTAL_AXIS && (deltaY = 0, deltaX = -1 * delta), orgEvent.wheelDeltaY !== void 0 && (deltaY = orgEvent.wheelDeltaY / 120), orgEvent.wheelDeltaX !== void 0 && (deltaX = -1 * orgEvent.wheelDeltaX / 120), typeof onMouseWheel == "function" && onMouseWheel(event2, delta, deltaX, deltaY);
}
return init(), { destroy };
}
function Resizable(options) {
let { resizeableElement, resizeableHandleElement, onResizeStart, onResize, onResizeEnd } = options;
if (!resizeableHandleElement || typeof resizeableHandleElement.addEventListener != "function")
throw new Error("[Slick.Resizable] You did not provide a valid html element that will be used for the handle to resize.");
function init() {
resizeableHandleElement.addEventListener("mousedown", resizeStartHandler), resizeableHandleElement.addEventListener("touchstart", resizeStartHandler);
}
function destroy() {
typeof resizeableHandleElement?.removeEventListener == "function" && (resizeableHandleElement.removeEventListener("mousedown", resizeStartHandler), resizeableHandleElement.removeEventListener("touchstart", resizeStartHandler));
}
function executeResizeCallbackWhenDefined(callback, e) {
if (typeof callback == "function")
return callback(e, { resizeableElement, resizeableHandleElement });
}
function resizeStartHandler(e) {
e.preventDefault();
let event2 = e.touches ? e.changedTouches[0] : e;
executeResizeCallbackWhenDefined(onResizeStart, event2) !== !1 && (document.body.addEventListener("mousemove", resizingHandler), document.body.addEventListener("mouseup", resizeEndHandler), document.body.addEventListener("touchmove", resizingHandler), document.body.addEventListener("touchend", resizeEndHandler));
}
function resizingHandler(e) {
e.preventDefault && e.type !== "touchmove" && e.preventDefault();
let event2 = e.touches ? e.changedTouches[0] : e;
typeof onResize == "function" && onResize(event2, { resizeableElement, resizeableHandleElement });
}
function resizeEndHandler(e) {
let event2 = e.touches ? e.changedTouches[0] : e;
executeResizeCallbackWhenDefined(onResizeEnd, event2), document.body.removeEventListener("mousemove", resizingHandler), document.body.removeEventListener("mouseup", resizeEndHandler), document.body.removeEventListener("touchmove", resizingHandler), document.body.removeEventListener("touchend", resizeEndHandler);
}
return init(), { destroy };
}
// src/plugins/slick.cellrangeselector.ts
var SlickEvent8 = SlickEvent, SlickEventHandler2 = SlickEventHandler, SlickRange3 = SlickRange, Draggable2 = Draggable, SlickCellRangeDecorator2 = SlickCellRangeDecorator, Utils12 = Utils, SlickCellRangeSelector = class {
constructor(options) {
// --
// public API
__publicField(this, "pluginName", "CellRangeSelector");
__publicField(this, "onBeforeCellRangeSelected", new SlickEvent8("onBeforeCellRangeSelected"));
__publicField(this, "onCellRangeSelected", new SlickEvent8("onCellRangeSelected"));
__publicField(this, "onCellRangeSelecting", new SlickEvent8("onCellRangeSelecting"));
// --
// protected props
__publicField(this, "_grid");
__publicField(this, "_currentlySelectedRange", null);
__publicField(this, "_canvas", null);
__publicField(this, "_decorator");
__publicField(this, "_gridOptions");
__publicField(this, "_activeCanvas");
__publicField(this, "_dragging", !1);
__publicField(this, "_handler", new SlickEventHandler2());
__publicField(this, "_options");
__publicField(this, "_defaults", {
autoScroll: !0,
minIntervalToShowNextCell: 30,
maxIntervalToShowNextCell: 600,
// better to a multiple of minIntervalToShowNextCell
accelerateInterval: 5,
// increase 5ms when cursor 1px outside the viewport.
selectionCss: {
border: "2px dashed blue"
}
});
// Frozen row & column variables
__publicField(this, "_rowOffset", 0);
__publicField(this, "_columnOffset", 0);
__publicField(this, "_isRightCanvas", !1);
__publicField(this, "_isBottomCanvas", !1);
// autoScroll related constiables
__publicField(this, "_activeViewport");
__publicField(this, "_autoScrollTimerId");
__publicField(this, "_draggingMouseOffset");
__publicField(this, "_moveDistanceForOneCell");
__publicField(this, "_xDelayForNextCell", 0);
__publicField(this, "_yDelayForNextCell", 0);
__publicField(this, "_viewportHeight", 0);
__publicField(this, "_viewportWidth", 0);
__publicField(this, "_isRowMoveRegistered", !1);
// Scrollings
__publicField(this, "_scrollLeft", 0);
__publicField(this, "_scrollTop", 0);
this._options = Utils12.extend(!0, {}, this._defaults, options);
}
init(grid) {
if (Draggable2 === void 0)
throw new Error('Slick.Draggable is undefined, make sure to import "slick.interactions.js"');
this._decorator = this._options.cellDecorator || new SlickCellRangeDecorator2(grid, this._options), this._grid = grid, Utils12.addSlickEventPubSubWhenDefined(grid.getPubSubService(), this), this._canvas = this._grid.getCanvasNode(), this._gridOptions = this._grid.getOptions(), this._handler.subscribe(this._grid.onScroll, this.handleScroll.bind(this)).subscribe(this._grid.onDragInit, this.handleDragInit.bind(this)).subscribe(this._grid.onDragStart, this.handleDragStart.bind(this)).subscribe(this._grid.onDrag, this.handleDrag.bind(this)).subscribe(this._grid.onDragEnd, this.handleDragEnd.bind(this));
}
destroy() {
this._handler.unsubscribeAll(), this._activeCanvas = null, this._activeViewport = null, this._canvas = null, this._decorator?.destroy();
}
getCellDecorator() {
return this._decorator;
}
handleScroll(_e, args) {
this._scrollTop = args.scrollTop, this._scrollLeft = args.scrollLeft;
}
handleDragInit(e) {
this._activeCanvas = this._grid.getActiveCanvasNode(e), this._activeViewport = this._grid.getActiveViewportNode(e);
let scrollbarDimensions = this._grid.getDisplayedScrollbarDimensions();
if (this._viewportWidth = this._activeViewport.offsetWidth - scrollbarDimensions.width, this._viewportHeight = this._activeViewport.offsetHeight - scrollbarDimensions.height, this._moveDistanceForOneCell = {
x: this._grid.getAbsoluteColumnMinWidth() / 2,
y: this._grid.getOptions().rowHeight / 2
}, this._isRowMoveRegistered = this.hasRowMoveManager(), this._rowOffset = 0, this._columnOffset = 0, this._isBottomCanvas = this._activeCanvas.classList.contains("grid-canvas-bottom"), this._gridOptions.frozenRow > -1 && this._isBottomCanvas) {
let canvasSelector = `.${this._grid.getUID()} .grid-canvas-${this._gridOptions.frozenBottom ? "bottom" : "top"}`, canvasElm = document.querySelector(canvasSelector);
canvasElm && (this._rowOffset = canvasElm.clientHeight || 0);
}
if (this._isRightCanvas = this._activeCanvas.classList.contains("grid-canvas-right"), this._gridOptions.frozenColumn > -1 && this._isRightCanvas) {
let canvasLeftElm = document.querySelector(`.${this._grid.getUID()} .grid-canvas-left`);
canvasLeftElm && (this._columnOffset = canvasLeftElm.clientWidth || 0);
}
e.stopImmediatePropagation(), e.preventDefault();
}
handleDragStart(e, dd) {
let cell = this._grid.getCellFromEvent(e);
if (cell && this.onBeforeCellRangeSelected.notify(cell).getReturnValue() !== !1 && this._grid.canCellBeSelected(cell.row, cell.cell) && (this._dragging = !0, e.stopImmediatePropagation()), !this._dragging)
return;
this._grid.focus();
let canvasOffset = Utils12.offset(this._canvas), startX = dd.startX - (canvasOffset?.left ?? 0);
this._gridOptions.frozenColumn >= 0 && this._isRightCanvas && (startX += this._scrollLeft);
let startY = dd.startY - (canvasOffset?.top ?? 0);
this._gridOptions.frozenRow >= 0 && this._isBottomCanvas && (startY += this._scrollTop);
let start = this._grid.getCellFromPoint(startX, startY);
return dd.range = { start, end: {} }, this._currentlySelectedRange = dd.range, this._decorator.show(new SlickRange3(start.row, start.cell));
}
handleDrag(evt, dd) {
if (!this._dragging && !this._isRowMoveRegistered)
return;
this._isRowMoveRegistered || evt.stopImmediatePropagation();
let e = evt.getNativeEvent();
if (this._options.autoScroll && (this._draggingMouseOffset = this.getMouseOffsetViewport(e, dd), this._draggingMouseOffset.isOutsideViewport))
return this.handleDragOutsideViewport();
this.stopIntervalTimer(), this.handleDragTo(e, dd);
}
getMouseOffsetViewport(e, dd) {
let targetEvent = e?.touches?.[0] ?? e, viewportLeft = this._activeViewport.scrollLeft, viewportTop = this._activeViewport.scrollTop, viewportRight = viewportLeft + this._viewportWidth, viewportBottom = viewportTop + this._viewportHeight, viewportOffset = Utils12.offset(this._activeViewport), viewportOffsetLeft = viewportOffset?.left ?? 0, viewportOffsetTop = viewportOffset?.top ?? 0, viewportOffsetRight = viewportOffsetLeft + this._viewportWidth, viewportOffsetBottom = viewportOffsetTop + this._viewportHeight, result = {
e,
dd,
viewport: {
left: viewportLeft,
top: viewportTop,
right: viewportRight,
bottom: viewportBottom,
offset: {
left: viewportOffsetLeft,
top: viewportOffsetTop,
right: viewportOffsetRight,
bottom: viewportOffsetBottom
}
},
// Consider the viewport as the origin, the `offset` is based on the coordinate system:
// the cursor is on the viewport's left/bottom when it is less than 0, and on the right/top when greater than 0.
offset: {
x: 0,
y: 0
},
isOutsideViewport: !1
};
return targetEvent.pageX < viewportOffsetLeft ? result.offset.x = targetEvent.pageX - viewportOffsetLeft : targetEvent.pageX > viewportOffsetRight && (result.offset.x = targetEvent.pageX - viewportOffsetRight), targetEvent.pageY < viewportOffsetTop ? result.offset.y = viewportOffsetTop - targetEvent.pageY : targetEvent.pageY > viewportOffsetBottom && (result.offset.y = viewportOffsetBottom - targetEvent.pageY), result.isOutsideViewport = !!result.offset.x || !!result.offset.y, result;
}
handleDragOutsideViewport() {
if (this._xDelayForNextCell = this._options.maxIntervalToShowNextCell - Math.abs(this._draggingMouseOffset.offset.x) * this._options.accelerateInterval, this._yDelayForNextCell = this._options.maxIntervalToShowNextCell - Math.abs(this._draggingMouseOffset.offset.y) * this._options.accelerateInterval, !this._autoScrollTimerId) {
let xTotalDelay = 0, yTotalDelay = 0;
this._autoScrollTimerId = window.setInterval(() => {
let xNeedUpdate = !1, yNeedUpdate = !1;
this._draggingMouseOffset.offset.x ? (xTotalDelay += this._options.minIntervalToShowNextCell, xNeedUpdate = xTotalDelay >= this._xDelayForNextCell) : xTotalDelay = 0, this._draggingMouseOffset.offset.y ? (yTotalDelay += this._options.minIntervalToShowNextCell, yNeedUpdate = yTotalDelay >= this._yDelayForNextCell) : yTotalDelay = 0, (xNeedUpdate || yNeedUpdate) && (xNeedUpdate && (xTotalDelay = 0), yNeedUpdate && (yTotalDelay = 0), this.handleDragToNewPosition(xNeedUpdate, yNeedUpdate));
}, this._options.minIntervalToShowNextCell);
}
}
handleDragToNewPosition(xNeedUpdate, yNeedUpdate) {
let pageX = this._draggingMouseOffset.e.pageX, pageY = this._draggingMouseOffset.e.pageY, mouseOffsetX = this._draggingMouseOffset.offset.x, mouseOffsetY = this._draggingMouseOffset.offset.y, viewportOffset = this._draggingMouseOffset.viewport.offset;
xNeedUpdate && mouseOffsetX && (mouseOffsetX > 0 ? pageX = viewportOffset.right + this._moveDistanceForOneCell.x : pageX = viewportOffset.left - this._moveDistanceForOneCell.x), yNeedUpdate && mouseOffsetY && (mouseOffsetY > 0 ? pageY = viewportOffset.top - this._moveDistanceForOneCell.y : pageY = viewportOffset.bottom + this._moveDistanceForOneCell.y), this.handleDragTo({ pageX, pageY }, this._draggingMouseOffset.dd);
}
stopIntervalTimer() {
this._autoScrollTimerId && (window.clearInterval(this._autoScrollTimerId), this._autoScrollTimerId = void 0);
}
handleDragTo(e, dd) {
let targetEvent = e?.touches?.[0] ?? e, canvasOffset = Utils12.offset(this._activeCanvas), end = this._grid.getCellFromPoint(
targetEvent.pageX - (canvasOffset?.left ?? 0) + this._columnOffset,
targetEvent.pageY - (canvasOffset?.top ?? 0) + this._rowOffset
);
if (!(this._gridOptions.frozenColumn >= 0 && !this._isRightCanvas && end.cell > this._gridOptions.frozenColumn || this._isRightCanvas && end.cell <= this._gridOptions.frozenColumn) && !(this._gridOptions.frozenRow >= 0 && !this._isBottomCanvas && end.row >= this._gridOptions.frozenRow || this._isBottomCanvas && end.row < this._gridOptions.frozenRow)) {
if (this._options.autoScroll && this._draggingMouseOffset) {
let endCellBox = this._grid.getCellNodeBox(end.row, end.cell);
if (!endCellBox)
return;
let viewport = this._draggingMouseOffset.viewport;
(endCellBox.left < viewport.left || endCellBox.right > viewport.right || endCellBox.top < viewport.top || endCellBox.bottom > viewport.bottom) && this._grid.scrollCellIntoView(end.row, end.cell);
}
if (this._grid.canCellBeSelected(end.row, end.cell) && dd?.range) {
dd.range.end = end;
let range = new SlickRange3(dd.range.start.row ?? 0, dd.range.start.cell ?? 0, end.row, end.cell);
this._decorator.show(range), this.onCellRangeSelecting.notify({
range
});
}
}
}
hasRowMoveManager() {
return !!(this._grid.getPluginByName("RowMoveManager") || this._grid.getPluginByName("CrossGridRowMoveManager"));
}
handleDragEnd(e, dd) {
this._decorator.hide(), this._dragging && (this._dragging = !1, e.stopImmediatePropagation(), this.stopIntervalTimer(), this.onCellRangeSelected.notify({
range: new SlickRange3(
dd.range.start.row ?? 0,
dd.range.start.cell ?? 0,
dd.range.end.row,
dd.range.end.cell
)
}));
}
getCurrentRange() {
return this._currentlySelectedRange;
}
};
// src/plugins/slick.cellselectionmodel.ts
var SlickEvent9 = SlickEvent, SlickEventData3 = SlickEventData, SlickRange4 = SlickRange, SlickCellRangeSelector2 = SlickCellRangeSelector, Utils13 = Utils, SlickCellSelectionModel = class {
constructor(options) {
// --
// public API
__publicField(this, "pluginName", "CellSelectionModel");
__publicField(this, "onSelectedRangesChanged", new SlickEvent9("onSelectedRangesChanged"));
// --
// protected props
__publicField(this, "_cachedPageRowCount", 0);
__publicField(this, "_dataView");
__publicField(this, "_grid");
__publicField(this, "_prevSelectedRow");
__publicField(this, "_prevKeyDown", "");
__publicField(this, "_ranges", []);
__publicField(this, "_selector");
__publicField(this, "_options");
__publicField(this, "_defaults", {
selectActiveCell: !0
});
options === void 0 || options.cellRangeSelector === void 0 ? this._selector = new SlickCellRangeSelector2({ selectionCss: { border: "2px solid black" } }) : this._selector = options.cellRangeSelector;
}
init(grid) {
this._options = Utils13.extend(!0, {}, this._defaults, this._options), this._grid = grid, grid.hasDataView() && (this._dataView = grid.getData()), this._grid.onActiveCellChanged.subscribe(this.handleActiveCellChange.bind(this)), this._grid.onKeyDown.subscribe(this.handleKeyDown.bind(this)), grid.registerPlugin(this._selector), this._selector.onCellRangeSelected.subscribe(this.handleCellRangeSelected.bind(this)), this._selector.onBeforeCellRangeSelected.subscribe(this.handleBeforeCellRangeSelected.bind(this));
}
destroy() {
this._grid.onActiveCellChanged.unsubscribe(this.handleActiveCellChange.bind(this)), this._grid.onKeyDown.unsubscribe(this.handleKeyDown.bind(this)), this._selector.onCellRangeSelected.unsubscribe(this.handleCellRangeSelected.bind(this)), this._selector.onBeforeCellRangeSelected.unsubscribe(this.handleBeforeCellRangeSelected.bind(this)), this._grid.unregisterPlugin(this._selector), this._selector?.destroy();
}
removeInvalidRanges(ranges) {
let result = [];
for (let i = 0; i < ranges.length; i++) {
let r = ranges[i];
this._grid.canCellBeSelected(r.fromRow, r.fromCell) && this._grid.canCellBeSelected(r.toRow, r.toCell) && result.push(r);
}
return result;
}
rangesAreEqual(range1, range2) {
let areDifferent = range1.length !== range2.length;
if (!areDifferent) {
for (let i = 0; i < range1.length; i++)
if (range1[i].fromCell !== range2[i].fromCell || range1[i].fromRow !== range2[i].fromRow || range1[i].toCell !== range2[i].toCell || range1[i].toRow !== range2[i].toRow) {
areDifferent = !0;
break;
}
}
return !areDifferent;
}
/** Provide a way to force a recalculation of page row count (for example on grid resize) */
resetPageRowCount() {
this._cachedPageRowCount = 0;
}
setSelectedRanges(ranges, caller = "SlickCellSelectionModel.setSelectedRanges") {
if ((!this._ranges || this._ranges.length === 0) && (!ranges || ranges.length === 0))
return;
let rangeHasChanged = !this.rangesAreEqual(this._ranges, ranges);
if (this._ranges = this.removeInvalidRanges(ranges), rangeHasChanged) {
let eventData = new SlickEventData3(new CustomEvent("click", { detail: { caller } }), this._ranges);
this.onSelectedRangesChanged.notify(this._ranges, eventData);
}
}
getSelectedRanges() {
return this._ranges;
}
refreshSelections() {
this.setSelectedRanges(this.getSelectedRanges());
}
handleBeforeCellRangeSelected(e) {
if (this._grid.getEditorLock().isActive())
return e.stopPropagation(), !1;
}
handleCellRangeSelected(_e, args) {
this._grid.setActiveCell(args.range.fromRow, args.range.fromCell, !1, !1, !0), this.setSelectedRanges([args.range]);
}
handleActiveCellChange(_e, args) {
this._prevSelectedRow = void 0;
let isCellDefined = Utils13.isDefined(args.cell), isRowDefined = Utils13.isDefined(args.row);
this._options?.selectActiveCell && isRowDefined && isCellDefined ? this.setSelectedRanges([new SlickRange4(args.row, args.cell)]) : (!this._options?.selectActiveCell || !isRowDefined && !isCellDefined) && this.setSelectedRanges([]);
}
isKeyAllowed(key, isShiftKeyPressed) {
return [
"ArrowLeft",
"ArrowRight",
"ArrowUp",
"ArrowDown",
"PageDown",
"PageUp",
"Home",
"End",
...isShiftKeyPressed ? [] : ["a", "A"]
].some((k) => k === key);
}
handleKeyDown(e) {
let ranges, last, colLn = this._grid.getColumns().length, active = this._grid.getActiveCell(), dataLn = 0;
if (this._dataView && "getPagingInfo" in this._dataView ? dataLn = this._dataView?.getPagingInfo().pageSize || this._dataView.getLength() : dataLn = this._grid.getDataLength(), active && (e.shiftKey || e.ctrlKey) && !e.altKey && this.isKeyAllowed(e.key, e.shiftKey)) {
ranges = this.getSelectedRanges().slice(), ranges.length || ranges.push(new SlickRange4(active.row, active.cell)), last = ranges.pop(), last.contains(active.row, active.cell) || (last = new SlickRange4(active.row, active.cell));
let dRow = last.toRow - last.fromRow, dCell = last.toCell - last.fromCell, toCell, toRow = 0;
e.ctrlKey && e.key?.toLowerCase() === "a" && (this._grid.setActiveCell(0, 0, !1, !1, !0), active.row = 0, active.cell = 0, toCell = colLn - 1, toRow = dataLn - 1);
let dirRow = active.row === last.fromRow ? 1 : -1, dirCell = active.cell === last.fromCell ? 1 : -1, isSingleKeyMove = e.key.startsWith("Arrow");
isSingleKeyMove && !e.ctrlKey ? (e.key === "ArrowLeft" ? dCell -= dirCell : e.key === "ArrowRight" ? dCell += dirCell : e.key === "ArrowUp" ? dRow -= dirRow : e.key === "ArrowDown" && (dRow += dirRow), toRow = active.row + dirRow * dRow) : (this._cachedPageRowCount < 1 && (this._cachedPageRowCount = this._grid.getViewportRowCount()), this._prevSelectedRow === void 0 && (this._prevSelectedRow = active.row), !e.ctrlKey && e.shiftKey && e.key === "Home" || e.ctrlKey && e.shiftKey && e.key === "ArrowLeft" ? (toCell = 0, toRow = active.row) : !e.ctrlKey && e.shiftKey && e.key === "End" || e.ctrlKey && e.shiftKey && e.key === "ArrowRight" ? (toCell = colLn - 1, toRow = active.row) : e.ctrlKey && e.shiftKey && e.key === "ArrowUp" ? toRow = 0 : e.ctrlKey && e.shiftKey && e.key === "ArrowDown" ? toRow = dataLn - 1 : e.ctrlKey && e.shiftKey && e.key === "Home" ? (toCell = 0, toRow = 0) : e.ctrlKey && e.shiftKey && e.key === "End" ? (toCell = colLn - 1, toRow = dataLn - 1) : e.key === "PageUp" ? (this._prevSelectedRow >= 0 && (toRow = this._prevSelectedRow - this._cachedPageRowCount), toRow < 0 && (toRow = 0)) : e.key === "PageDown" && (this._prevSelectedRow <= dataLn - 1 && (toRow = this._prevSelectedRow + this._cachedPageRowCount), toRow > dataLn - 1 && (toRow = dataLn - 1)), this._prevSelectedRow = toRow), toCell ?? (toCell = active.cell + dirCell * dCell);
let new_last = new SlickRange4(active.row, active.cell, toRow, toCell);
if (this.removeInvalidRanges([new_last]).length) {
ranges.push(new_last);
let viewRow = dirRow > 0 ? new_last.toRow : new_last.fromRow, viewCell = dirCell > 0 ? new_last.toCell : new_last.fromCell;
isSingleKeyMove ? (this._grid.scrollRowIntoView(viewRow), this._grid.scrollCellIntoView(viewRow, viewCell)) : (this._grid.scrollRowIntoView(toRow), this._grid.scrollCellIntoView(toRow, viewCell));
} else
ranges.push(last);
this.setSelectedRanges(ranges), e.preventDefault(), e.stopPropagation(), this._prevKeyDown = e.key;
}
}
};
// src/plugins/slick.checkboxselectcolumn.ts
var BindingEventService7 = BindingEventService, SlickEventHandler3 = SlickEventHandler, Utils14 = Utils, SlickCheckboxSelectColumn = class {
constructor(options) {
// --
// public API
__publicField(this, "pluginName", "CheckboxSelectColumn");
// --
// protected props
__publicField(this, "_dataView");
__publicField(this, "_grid");
__publicField(this, "_isUsingDataView", !1);
__publicField(this, "_selectableOverride", null);
__publicField(this, "_headerRowNode");
__publicField(this, "_selectAll_UID");
__publicField(this, "_handler", new SlickEventHandler3());
__publicField(this, "_selectedRowsLookup", {});
__publicField(this, "_checkboxColumnCellIndex", null);
__publicField(this, "_options");
__publicField(this, "_defaults", {
columnId: "_checkbox_selector",
cssClass: void 0,
hideSelectAllCheckbox: !1,
name: "",
toolTip: "Select/Deselect All",
width: 30,
reorderable: !1,
applySelectOnAllPages: !1,
// defaults to false, when that is enabled the "Select All" will be applied to all pages (when using Pagination)
hideInColumnTitleRow: !1,
hideInFilterHeaderRow: !0
});
__publicField(this, "_isSelectAllChecked", !1);
__publicField(this, "_bindingEventService");
this._bindingEventService = new BindingEventService7(), this._options = Utils14.extend(!0, {}, this._defaults, options), this._selectAll_UID = this.createUID(), typeof this._options.selectableOverride == "function" && this.selectableOverride(this._options.selectableOverride);
}
init(grid) {
this._grid = grid, this._isUsingDataView = !Array.isArray(grid.getData()), this._isUsingDataView && (this._dataView = grid.getData()), this._handler.subscribe(this._grid.onSelectedRowsChanged, this.handleSelectedRowsChanged.bind(this)).subscribe(this._grid.onClick, this.handleClick.bind(this)).subscribe(this._grid.onKeyDown, this.handleKeyDown.bind(this)).subscribe(this._grid.onAfterSetColumns, () => this.renderSelectAllCheckbox(this._isSelectAllChecked)), this._isUsingDataView && this._dataView && this._options.applySelectOnAllPages && this._handler.subscribe(this._dataView.onSelectedRowIdsChanged, this.handleDataViewSelectedIdsChanged.bind(this)).subscribe(this._dataView.onPagingInfoChanged, this.handleDataViewSelectedIdsChanged.bind(this)), this._options.hideInFilterHeaderRow || this.addCheckboxToFilterHeaderRow(grid), this._options.hideInColumnTitleRow || this._handler.subscribe(this._grid.onHeaderClick, this.handleHeaderClick.bind(this));
}
destroy() {
this._handler.unsubscribeAll(), this._bindingEventService.unbindAll();
}
getOptions() {
return this._options;
}
setOptions(options) {
if (this._options = Utils14.extend(!0, {}, this._options, options), this._options.hideSelectAllCheckbox)
this.hideSelectAllFromColumnHeaderTitleRow(), this.hideSelectAllFromColumnHeaderFilterRow();
else if (this._options.hideInColumnTitleRow ? (this.hideSelectAllFromColumnHeaderTitleRow(), this._options.name && this._grid.updateColumnHeader(this._options.columnId || "", this._options.name, "")) : (this.renderSelectAllCheckbox(this._isSelectAllChecked), this._handler.subscribe(this._grid.onHeaderClick, this.handleHeaderClick.bind(this))), this._options.hideInFilterHeaderRow)
this.hideSelectAllFromColumnHeaderFilterRow();
else {
let selectAllContainerElm = this._headerRowNode?.querySelector("#filter-checkbox-selectall-container");
if (selectAllContainerElm) {
selectAllContainerElm.style.display = "flex";
let selectAllInputElm = selectAllContainerElm.querySelector('input[type="checkbox"]');
selectAllInputElm && (selectAllInputElm.checked = this._isSelectAllChecked);
}
}
}
hideSelectAllFromColumnHeaderTitleRow() {
this._grid.updateColumnHeader(this._options.columnId || "", this._options.name || "", "");
}
hideSelectAllFromColumnHeaderFilterRow() {
let selectAllContainerElm = this._headerRowNode?.querySelector("#filter-checkbox-selectall-container");
selectAllContainerElm && (selectAllContainerElm.style.display = "none");
}
handleSelectedRowsChanged() {
let selectedRows = this._grid.getSelectedRows(), lookup = {}, row = 0, i = 0, k = 0, disabledCount = 0;
if (typeof this._selectableOverride == "function")
for (k = 0; k < this._grid.getDataLength(); k++) {
let dataItem = this._grid.getDataItem(k);
this.checkSelectableOverride(i, dataItem, this._grid) || disabledCount++;
}
let removeList = [];
for (i = 0; i < selectedRows.length; i++) {
row = selectedRows[i];
let rowItem = this._grid.getDataItem(row);
this.checkSelectableOverride(i, rowItem, this._grid) ? (lookup[row] = !0, lookup[row] !== this._selectedRowsLookup[row] && (this._grid.invalidateRow(row), delete this._selectedRowsLookup[row])) : removeList.push(row);
}
if (typeof this._selectedRowsLookup == "object" && Object.keys(this._selectedRowsLookup).forEach((selectedRow) => {
selectedRow !== void 0 && this._grid.invalidateRow(+selectedRow);
}), this._selectedRowsLookup = lookup, this._grid.render(), this._isSelectAllChecked = (selectedRows?.length ?? 0) + disabledCount >= this._grid.getDataLength(), (!this._isUsingDataView || !this._options.applySelectOnAllPages) && (!this._options.hideInColumnTitleRow && !this._options.hideSelectAllCheckbox && this.renderSelectAllCheckbox(this._isSelectAllChecked), !this._options.hideInFilterHeaderRow)) {
let selectAllElm = this._headerRowNode?.querySelector(`#header-filter-selector${this._selectAll_UID}`);
selectAllElm && (selectAllElm.checked = this._isSelectAllChecked);
}
if (removeList.length > 0) {
for (i = 0; i < removeList.length; i++) {
let remIdx = selectedRows.indexOf(removeList[i]);
selectedRows.splice(remIdx, 1);
}
this._grid.setSelectedRows(selectedRows, "click.cleanup");
}
}
handleDataViewSelectedIdsChanged() {
let selectedIds = this._dataView.getAllSelectedFilteredIds(), filteredItems = this._dataView.getFilteredItems(), disabledCount = 0;
if (typeof this._selectableOverride == "function" && selectedIds.length > 0)
for (let k = 0; k < this._dataView.getItemCount(); k++) {
let dataItem = this._dataView.getItemByIdx(k), idProperty = this._dataView.getIdPropertyName(), dataItemId = dataItem[idProperty];
filteredItems.findIndex(function(item) {
return item[idProperty] === dataItemId;
}) >= 0 && !this.checkSelectableOverride(k, dataItem, this._grid) && disabledCount++;
}
if (this._isSelectAllChecked = (selectedIds && selectedIds.length) + disabledCount >= filteredItems.length, !this._options.hideInColumnTitleRow && !this._options.hideSelectAllCheckbox && this.renderSelectAllCheckbox(this._isSelectAllChecked), !this._options.hideInFilterHeaderRow) {
let selectAllElm = this._headerRowNode?.querySelector(`#header-filter-selector${this._selectAll_UID}`);
selectAllElm && (selectAllElm.checked = this._isSelectAllChecked);
}
}
handleKeyDown(e, args) {
e.which === 32 && this._grid.getColumns()[args.cell].id === this._options.columnId && ((!this._grid.getEditorLock().isActive() || this._grid.getEditorLock().commitCurrentEdit()) && this.toggleRowSelection(args.row), e.preventDefault(), e.stopImmediatePropagation());
}
handleClick(e, args) {
if (this._grid.getColumns()[args.cell].id === this._options.columnId && e.target.type === "checkbox") {
if (this._grid.getEditorLock().isActive() && !this._grid.getEditorLock().commitCurrentEdit()) {
e.preventDefault(), e.stopImmediatePropagation();
return;
}
this.toggleRowSelection(args.row), e.stopPropagation(), e.stopImmediatePropagation();
}
}
toggleRowSelection(row) {
let dataContext = this._grid.getDataItem(row);
if (this.checkSelectableOverride(row, dataContext, this._grid)) {
if (this._selectedRowsLookup[row]) {
let newSelectedRows = this._grid.getSelectedRows().filter((n) => n !== row);
this._grid.setSelectedRows(newSelectedRows, "click.toggle");
} else
this._grid.setSelectedRows(this._grid.getSelectedRows().concat(row), "click.toggle");
this._grid.setActiveCell(row, this.getCheckboxColumnCellIndex());
}
}
selectRows(rowArray) {
let addRows = [];
for (let i = 0, l = rowArray.length; i < l; i++)
this._selectedRowsLookup[rowArray[i]] || (addRows[addRows.length] = rowArray[i]);
this._grid.setSelectedRows(this._grid.getSelectedRows().concat(addRows), "SlickCheckboxSelectColumn.selectRows");
}
deSelectRows(rowArray) {
let removeRows = [];
for (let i = 0, l = rowArray.length; i < l; i++)
this._selectedRowsLookup[rowArray[i]] && (removeRows[removeRows.length] = rowArray[i]);
this._grid.setSelectedRows(this._grid.getSelectedRows().filter((n) => removeRows.indexOf(n) < 0), "SlickCheckboxSelectColumn.deSelectRows");
}
handleHeaderClick(e, args) {
if (args.column.id === this._options.columnId && e.target.type === "checkbox") {
if (this._grid.getEditorLock().isActive() && !this._grid.getEditorLock().commitCurrentEdit()) {
e.preventDefault(), e.stopImmediatePropagation();
return;
}
let isAllSelected = e.target.checked, caller = isAllSelected ? "click.selectAll" : "click.unselectAll", rows = [];
if (isAllSelected) {
for (let i = 0; i < this._grid.getDataLength(); i++) {
let rowItem = this._grid.getDataItem(i);
!rowItem.__group && !rowItem.__groupTotals && this.checkSelectableOverride(i, rowItem, this._grid) && rows.push(i);
}
isAllSelected = !0;
}
if (this._isUsingDataView && this._dataView && this._options.applySelectOnAllPages) {
let ids = [], filteredItems = this._dataView.getFilteredItems();
for (let j = 0; j < filteredItems.length; j++) {
let dataviewRowItem = filteredItems[j];
this.checkSelectableOverride(j, dataviewRowItem, this._grid) && ids.push(dataviewRowItem[this._dataView.getIdPropertyName()]);
}
this._dataView.setSelectedIds(ids, { isRowBeingAdded: isAllSelected });
}
this._grid.setSelectedRows(rows, caller), e.stopPropagation(), e.stopImmediatePropagation();
}
}
getCheckboxColumnCellIndex() {
if (this._checkboxColumnCellIndex === null) {
this._checkboxColumnCellIndex = 0;
let colArr = this._grid.getColumns();
for (let i = 0; i < colArr.length; i++)
colArr[i].id === this._options.columnId && (this._checkboxColumnCellIndex = i);
}
return this._checkboxColumnCellIndex;
}
/**
* use a DocumentFragment to return a fragment including an then a