UNPKG

igniteui-react-grids

Version:

Ignite UI React Grid components.

253 lines (252 loc) 9.05 kB
import { createComponent } from "@lit/react"; import { html, noChange } from "lit"; import { createPortal } from "react-dom"; import { AsyncDirective, directive } from "lit/async-directive.js"; //#region src/backfills.ts var DATA_CONTEXT_PROP = "dataContext"; var once = false; /** * Creates a proxy around template context data that adds back * the `dataContext` prop returning the original data */ function withDataContext(data) { return new Proxy(data, { get(target, prop, receiver) { if (prop === DATA_CONTEXT_PROP) { if (!once) { once = true; console.warn("dataContext is deprecated and template context props are now available as the root object and can be accessed directly"); } return target; } return Reflect.get(target, prop, receiver); } }); } //#endregion //#region src/equal.ts function equal(a, b, visited = /* @__PURE__ */ new WeakSet()) { if (Object.is(a, b)) return true; if (isObject(a) && isObject(b)) { if (a.constructor !== b.constructor) return false; if (visited.has(a) && visited.has(b)) return true; visited.add(a); visited.add(b); if (isRegExp(a) && isRegExp(b)) return a.source === b.source && a.flags === b.flags; if (a instanceof Map && b instanceof Map) { if (a.size !== b.size) return false; for (const [keyA, valueA] of a.entries()) { let found = false; for (const [keyB, valueB] of b.entries()) if (equal(keyA, keyB, visited) && equal(valueA, valueB, visited)) { found = true; break; } if (!found) return false; } return true; } if (a instanceof Set && b instanceof Set) { if (a.size !== b.size) return false; for (const valueA of a) { let found = false; for (const valueB of b) if (equal(valueA, valueB, visited)) { found = true; break; } if (!found) return false; } return true; } if (Array.isArray(a) && Array.isArray(b)) { const length = a.length; if (length !== b.length) return false; for (let i = 0; i < length; i++) if (!equal(a[i], b[i], visited)) return false; return true; } if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf(); if (a.toString !== Object.prototype.toString) return a.toString() === b.toString(); const aKeys = Object.keys(a); const bKeys = Object.keys(b); if (aKeys.length !== bKeys.length) return false; for (const key of aKeys) if (!Object.hasOwn(b, key)) return false; for (const key of aKeys) if (!equal(a[key], b[key], visited)) return false; visited.delete(a); visited.delete(b); return true; } return false; } function isObject(value) { return value != null && typeof value === "object"; } function isRegExp(value) { return value != null && value.constructor === RegExp; } //#endregion //#region src/random-uuid.ts /** * Use the function to get a random UUID string when secure context is not guaranteed making crypto.randomUUID unavailable. * @returns A random UUID string. */ function getUUID() { if (typeof crypto.randomUUID === "function") return crypto.randomUUID(); const bytes = /* @__PURE__ */ new Uint8Array(16); crypto.getRandomValues(bytes); bytes[6] = bytes[6] & 15 | 64; bytes[8] = bytes[8] & 63 | 128; const a = [...bytes].map((b) => b.toString(16).padStart(2, "0")).join(""); return `${a.slice(0, 8)}-${a.slice(8, 12)}-${a.slice(12, 16)}-${a.slice(16, 20)}-${a.slice(20)}`; } //#endregion //#region src/render-props.ts var REQUEST_REMOVE = Symbol("renderer-remove"); var NOT_SET = Symbol("not-set"); function createRequestData(name, data, node, key) { return { name, data: data === REQUEST_REMOVE ? data : withDataContext(data), slotName: key !== void 0 ? `${name}${key}` : name, node }; } var RequestRenderer = class extends AsyncDirective { constructor(..._args) { super(..._args); this._key = getUUID(); this._part = null; this._callback = null; this._state = { previous: NOT_SET, current: void 0 }; } get _renderNode() { return this._part?.deref()?.parentNode; } _shouldUpdateNG(_data) { return true; } _shouldUpdate() { const data = this._state.current; if (Reflect.has(data, "implicit")) return this._shouldUpdateNG(data); if (equal(this._state.previous, data)) return false; this._state.previous = data; return true; } render(_callback, _name, _data) { return noChange; } update(part, [callback, name, data]) { this._callback = new WeakRef(callback); this._name = name; this._state.current = data; this._part = new WeakRef(part); if (this.isConnected && callback && this._shouldUpdate()) callback(createRequestData(this._name, this._state.current, this._renderNode, this._key)); return noChange; } reconnected() { const callback = this._callback?.deref(); if (callback && this._shouldUpdate()) callback(createRequestData(this._name, this._state.current, this._renderNode, this._key)); } disconnected() { const callback = this._callback?.deref(); if (callback) { callback(createRequestData(this._name, REQUEST_REMOVE, this._renderNode, this._key)); this._state.previous = NOT_SET; } } }; var requestRenderer = directive(RequestRenderer); //#endregion //#region src/react-props.tsx /** biome-ignore-all lint/complexity/noBannedTypes: use `{}` literals */ var createComponent$1 = ({ react: React, tagName, elementClass, events, displayName, renderProps, moveBackOnDelete }) => { if ("register" in elementClass) elementClass.register(); if (!renderProps && !moveBackOnDelete) return createComponent({ react: React, tagName, elementClass, events, displayName }); const component = createComponent({ react: React, tagName, elementClass, events: events ?? {}, displayName }); return React.forwardRef((props, ref) => { const listeners = React.useRef(/* @__PURE__ */ new Map()); const elementRef = React.useRef(null); const projectionParent = React.useRef(null); const [renderers, setRenderers] = React.useState(/* @__PURE__ */ new Map()); const outProps = {}; const portals = {}; React.useLayoutEffect(() => { if (!moveBackOnDelete) return; const prevParent = projectionParent.current?.deref(); if (prevParent && elementRef.current && prevParent !== elementRef.current.parentElement) { prevParent.appendChild(elementRef.current); projectionParent.current = null; } return () => { const element = elementRef.current; if (!element) return; const creationParent = element.ngElementStrategy?.parentElement?.deref(); if (creationParent && creationParent !== element.parentElement) { if (element.parentElement) projectionParent.current = new WeakRef(element.parentElement); creationParent.appendChild(element); } }; }, [moveBackOnDelete]); const renderFunc = (req) => { if (req.data === REQUEST_REMOVE) renderers.delete(req.slotName); else renderers.set(req.slotName, createPortal(portals[req.name]?.(req.data), req.node, req.slotName)); setRenderers(() => new Map(renderers)); }; const processProps = (propMap, propDefinitions, outProps, prefix = "") => { for (const prop in propMap) { const fullPropName = prefix ? `${prefix}.${prop}` : prop; const rendererName = propDefinitions?.[prop]; if (rendererName !== void 0 && typeof rendererName === "string") if (listeners.current.has(fullPropName)) outProps[prop] = listeners.current.get(fullPropName); else { portals[rendererName] = propMap[prop]; const patched = createPatched(renderFunc, rendererName); outProps[prop] = patched; listeners.current.set(fullPropName, patched); } else if (typeof propMap[prop] === "object" && propMap[prop] !== null && propDefinitions?.[prop] && typeof propDefinitions[prop] === "object") { outProps[prop] = {}; processProps(propMap[prop], propDefinitions?.[prop], outProps[prop], fullPropName); } else outProps[prop] = propMap[prop]; } }; for (const key of listeners.current.keys()) if (!hasNestedProperty(props, key)) listeners.current.delete(key); processProps(props, renderProps ?? {}, outProps); const propsWithChildren = props; if (listeners.current.size) Object.assign(outProps, { children: [...React.Children.toArray(propsWithChildren.children), ...renderers.values()] }); else Object.assign(outProps, { children: React.Children.toArray(propsWithChildren.children) }); return React.createElement(component, { ...outProps, ref: React.useCallback((node) => { elementRef.current = node; if (typeof ref === "function") ref(node); else if (ref !== null) ref.current = node; }, [ref]) }); }); }; function createPatched(callback, propertyName) { return (ctx) => html`${requestRenderer(callback, propertyName, ctx)}`; } function hasNestedProperty(object, path) { const parts = path.split("."); let current = object; for (const part of parts) { if (current === void 0 || current === null || typeof current !== "object") return false; current = current[part]; } return current !== void 0; } //#endregion export { createComponent$1 as t }; //# sourceMappingURL=react-props-BiWO5bqp.js.map