@meonode/ui 0.4.5 → 0.4.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -5
- package/dist/components/meonode-unmounter.client.d.ts +19 -0
- package/dist/components/meonode-unmounter.client.d.ts.map +1 -0
- package/dist/components/meonode-unmounter.client.js +13 -0
- package/dist/components/registry.client.d.ts +9 -1
- package/dist/components/registry.client.d.ts.map +1 -1
- package/dist/components/registry.client.js +14 -1
- package/dist/components/styled-renderer.client.d.ts.map +1 -1
- package/dist/components/styled-renderer.client.js +2 -2
- package/dist/constants/common.const.d.ts +2 -1
- package/dist/constants/common.const.d.ts.map +1 -1
- package/dist/constants/common.const.js +1 -1
- package/dist/core.node.d.ts +43 -125
- package/dist/core.node.d.ts.map +1 -1
- package/dist/core.node.js +51 -186
- package/dist/helper/common.helper.d.ts +1 -1
- package/dist/helper/common.helper.d.ts.map +1 -1
- package/dist/hoc/component.hoc.js +2 -2
- package/dist/main.d.ts +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +3 -2
- package/dist/types/node.type.d.ts +3 -17
- package/dist/types/node.type.d.ts.map +1 -1
- package/dist/util/mount-tracker.util.d.ts +26 -0
- package/dist/util/mount-tracker.util.d.ts.map +1 -0
- package/dist/util/mount-tracker.util.js +15 -0
- package/dist/util/navigation-cache-manager.util.d.ts +36 -0
- package/dist/util/navigation-cache-manager.util.d.ts.map +1 -0
- package/dist/util/navigation-cache-manager.util.js +19 -0
- package/dist/util/node.util.d.ts +155 -0
- package/dist/util/node.util.d.ts.map +1 -0
- package/dist/util/node.util.js +172 -0
- package/dist/util/theme.util.d.ts +108 -0
- package/dist/util/theme.util.d.ts.map +1 -0
- package/dist/util/theme.util.js +117 -0
- package/package.json +5 -2
- package/dist/helper/mount-tracker.helper.d.ts +0 -16
- package/dist/helper/mount-tracker.helper.d.ts.map +0 -1
- package/dist/helper/mount-tracker.helper.js +0 -8
- package/dist/helper/navigation-cache-manager.helper.d.ts +0 -38
- package/dist/helper/navigation-cache-manager.helper.d.ts.map +0 -1
- package/dist/helper/navigation-cache-manager.helper.js +0 -34
- package/dist/helper/node.helper.d.ts +0 -70
- package/dist/helper/node.helper.d.ts.map +0 -1
- package/dist/helper/node.helper.js +0 -112
- package/dist/helper/safe-cache-manager.helper.d.ts +0 -21
- package/dist/helper/safe-cache-manager.helper.d.ts.map +0 -1
- package/dist/helper/safe-cache-manager.helper.js +0 -33
- package/dist/helper/theme.helper.d.ts +0 -15
- package/dist/helper/theme.helper.d.ts.map +0 -1
- package/dist/helper/theme.helper.js +0 -16
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
function _typeof(a){"@babel/helpers - typeof";return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},_typeof(a)}function _defineProperty(a,b,c){return(b=_toPropertyKey(b))in a?Object.defineProperty(a,b,{value:c,enumerable:!0,configurable:!0,writable:!0}):a[b]=c,a}function _toPropertyKey(a){var b=_toPrimitive(a,"string");return"symbol"==_typeof(b)?b:b+""}function _toPrimitive(a,b){if("object"!=_typeof(a)||!a)return a;var c=a[Symbol.toPrimitive];if(void 0!==c){var d=c.call(a,b||"default");if("object"!=_typeof(d))return d;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===b?String:Number)(a)}import{__DEBUG__}from"../constants/common.const.js";import{BaseNode}from"../core.node.js";import{MountTrackerUtil}from"./mount-tracker.util.js";/**
|
|
2
|
+
* Lightweight navigation handler that clears cache on SPA navigation.
|
|
3
|
+
*/export class NavigationCacheManagerUtil{constructor(){var a=this;/**
|
|
4
|
+
* Debounced navigation handler. Clears mounted element cache and props cache.
|
|
5
|
+
*/_defineProperty(this,"_isListening",!1),_defineProperty(this,"_cleanupTimeout",null),_defineProperty(this,"_handleNavigation",function(){a._cleanupTimeout&&clearTimeout(a._cleanupTimeout);var b=BaseNode.elementCache.size,c=100>b?50:500>b?100:200;a._cleanupTimeout=setTimeout(function(){var a=BaseNode.propProcessingCache.size,b=0;// Only clean UNMOUNTED elements
|
|
6
|
+
BaseNode.elementCache.keys().forEach(function(a){MountTrackerUtil.mountedNodes.has(a)||(BaseNode.elementCache["delete"](a),b++)}),200<a&&BaseNode.propProcessingCache.clear(),__DEBUG__&&console.log("[MeoNode] Navigation: cleared ".concat(b," unmounted elements, ").concat(a," props entries"))},c)})}static getInstance(){return this._instance||(this._instance=new NavigationCacheManagerUtil),this._instance}/**
|
|
7
|
+
* Start listening for navigation events. Idempotent.
|
|
8
|
+
*/start(){this._isListening||"undefined"==typeof window||(// Setup automatic cleanup on page unload
|
|
9
|
+
this._isListening=!0,window.addEventListener("popstate",this._handleNavigation),this._patchHistoryMethods(),this._setupAutoCleanup(),__DEBUG__&&console.log("[MeoNode] NavigationCacheManagerUtil started"))}/**
|
|
10
|
+
* Stops listening for navigation events and restores original browser APIs.
|
|
11
|
+
* This is important for cleanup during HMR or when unmounting the library.
|
|
12
|
+
*/_stop(){this._isListening&&"undefined"!=typeof window&&(window.removeEventListener("popstate",this._handleNavigation),this._cleanupTimeout&&(clearTimeout(this._cleanupTimeout),this._cleanupTimeout=null),this._isListening=!1,__DEBUG__&&console.log("[MeoNode] NavigationCacheManagerUtil stopped"))}/**
|
|
13
|
+
* Patch history.pushState/replaceState to detect SPA navigation.
|
|
14
|
+
*/_patchHistoryMethods(){var a=this;NavigationCacheManagerUtil._isPatched||(NavigationCacheManagerUtil._originalPushState=history.pushState,NavigationCacheManagerUtil._originalReplaceState=history.replaceState,history.pushState=function(){for(var b=arguments.length,c=Array(b),d=0;d<b;d++)c[d]=arguments[d];NavigationCacheManagerUtil._originalPushState.apply(history,c),a._handleNavigation()},history.replaceState=function(){for(var b=arguments.length,c=Array(b),d=0;d<b;d++)c[d]=arguments[d];NavigationCacheManagerUtil._originalReplaceState.apply(history,c),a._handleNavigation()},NavigationCacheManagerUtil._isPatched=!0)}/**
|
|
15
|
+
* Setup automatic cleanup on page unload.
|
|
16
|
+
* Covers HMR, navigation away, and browser close.
|
|
17
|
+
*/_setupAutoCleanup(){var a=this;// Only set up once
|
|
18
|
+
window.__MEONODE_CLEANUP_REGISTERED||(// Handle page unload (navigation away, refresh, close)
|
|
19
|
+
window.addEventListener("beforeunload",function(){a._stop(),BaseNode.clearCaches()}),window.__MEONODE_CLEANUP_REGISTERED=!0)}}_defineProperty(NavigationCacheManagerUtil,"_instance",null),_defineProperty(NavigationCacheManagerUtil,"_originalPushState",null),_defineProperty(NavigationCacheManagerUtil,"_originalReplaceState",null),_defineProperty(NavigationCacheManagerUtil,"_isPatched",!1);
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import React, { type ReactNode } from 'react';
|
|
2
|
+
import type { FunctionRendererProps, NodeElement, NodeElementType, NodeFunction, NodeInstance, NodeProps, DependencyList, NodePortal, FinalNodeProps } from '../types/node.type.js';
|
|
3
|
+
/**
|
|
4
|
+
* NodeUtil provides a collection of static utility methods and properties
|
|
5
|
+
* used internally by BaseNode for various tasks such as hashing, shallow comparison,
|
|
6
|
+
* and stable element ID generation. This centralizes common helper functions,
|
|
7
|
+
* improving modularity and maintainability of the core library.
|
|
8
|
+
*/
|
|
9
|
+
export declare class NodeUtil {
|
|
10
|
+
private constructor();
|
|
11
|
+
static isServer: boolean;
|
|
12
|
+
private static _functionSignatureCache;
|
|
13
|
+
private static readonly CACHE_SIZE_LIMIT = 500;
|
|
14
|
+
private static readonly CACHE_CLEANUP_BATCH = 50;
|
|
15
|
+
private static readonly CRITICAL_PROP_PREFIXES;
|
|
16
|
+
private static readonly CRITICAL_PROPS;
|
|
17
|
+
static portalInfrastructure: WeakMap<NodeInstance, {
|
|
18
|
+
domElement: HTMLDivElement;
|
|
19
|
+
reactRoot: NodePortal & {
|
|
20
|
+
render(children: ReactNode): void;
|
|
21
|
+
};
|
|
22
|
+
}>;
|
|
23
|
+
/**
|
|
24
|
+
* Type guard to check if an object is a NodeInstance.
|
|
25
|
+
*
|
|
26
|
+
* A NodeInstance is expected to be a non-null object with:
|
|
27
|
+
* - an 'element' property,
|
|
28
|
+
* - a 'render' method,
|
|
29
|
+
* - a 'toPortal' method,
|
|
30
|
+
* - and an 'isBaseNode' property.
|
|
31
|
+
* @param obj The object to check.
|
|
32
|
+
* @returns True if the object is a NodeInstance, false otherwise.
|
|
33
|
+
*/
|
|
34
|
+
static isNodeInstance: (obj: unknown) => obj is NodeInstance;
|
|
35
|
+
/**
|
|
36
|
+
* Determines if a given string `k` is a valid CSS style property.
|
|
37
|
+
* This check is performed only on the client-side by checking if the property exists in `document.body.style`.
|
|
38
|
+
* On the server-side, it always returns `false`.
|
|
39
|
+
* @param k The string to check.
|
|
40
|
+
*/
|
|
41
|
+
static isStyleProp: (k: string) => boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Combines FNV-1a and djb2 hash functions for a more robust signature.
|
|
44
|
+
* @method hashString
|
|
45
|
+
*/
|
|
46
|
+
static hashString(str: string): string;
|
|
47
|
+
/**
|
|
48
|
+
* Performs a shallow equality check between two objects.
|
|
49
|
+
* @method shallowEqual
|
|
50
|
+
*/
|
|
51
|
+
static shallowEqual(a: Record<string, any>, b: Record<string, any>): boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Creates a unique, stable signature from the element type and props.
|
|
54
|
+
* This signature includes the element's type to prevent collisions between different components
|
|
55
|
+
* and handles primitive values in arrays and objects for better caching.
|
|
56
|
+
* @method createPropSignature
|
|
57
|
+
*/
|
|
58
|
+
static createPropSignature(element: NodeElementType, props: Record<string, any>): string | undefined;
|
|
59
|
+
/**
|
|
60
|
+
* Extracts "critical" props from a given set of props. Critical props are those
|
|
61
|
+
* that are frequently used for styling or event handling, such as `on*` handlers,
|
|
62
|
+
* `aria-*` attributes, `data-*` attributes, `css`, `className`, and `style`.
|
|
63
|
+
* This method is used to optimize prop processing by focusing on props that are
|
|
64
|
+
* most likely to influence rendering or behavior.
|
|
65
|
+
*/
|
|
66
|
+
static extractCriticalProps(props: Record<string, any>, keys: string[]): Record<string, any>;
|
|
67
|
+
/**
|
|
68
|
+
* Retrieves computed CSS props from the cache with LRU tracking.
|
|
69
|
+
* Access time and hit count are tracked for smarter eviction.
|
|
70
|
+
* @method getCachedCssProps
|
|
71
|
+
*/
|
|
72
|
+
static getCachedCssProps(cacheableProps: Record<string, any>, signature?: string): {
|
|
73
|
+
cssProps: Record<string, any>;
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Implements an LRU eviction strategy that removes multiple entries at once.
|
|
77
|
+
* It uses a scoring system where older and less frequently used entries have a higher eviction priority.
|
|
78
|
+
* @method _evictLRUEntries
|
|
79
|
+
*/
|
|
80
|
+
private static _evictLRUEntries;
|
|
81
|
+
/**
|
|
82
|
+
* The main prop processing pipeline. It separates cacheable and non-cacheable props,
|
|
83
|
+
* generates a signature for caching, and assembles the final props object.
|
|
84
|
+
* @method processProps
|
|
85
|
+
*/
|
|
86
|
+
static processProps(element: NodeElementType, rawProps?: Partial<NodeProps<NodeElementType>>, stableKey?: string): FinalNodeProps;
|
|
87
|
+
/**
|
|
88
|
+
* Processes and normalizes children of the node.
|
|
89
|
+
* Converts raw children (React elements, primitives, or other BaseNodes) into a consistent format.
|
|
90
|
+
* @param children The raw children to process.
|
|
91
|
+
* @param disableEmotion If true, emotion styling will be disabled for these children.
|
|
92
|
+
* @param parentStableKey The stable key of the parent node, used for generating unique keys for children.
|
|
93
|
+
*/
|
|
94
|
+
private static _processChildren;
|
|
95
|
+
/**
|
|
96
|
+
* Determines if a node should update based on its dependency array.
|
|
97
|
+
* Uses a shallow comparison, similar to React's `useMemo` and `useCallback`.
|
|
98
|
+
* @method shouldNodeUpdate
|
|
99
|
+
*/
|
|
100
|
+
static shouldNodeUpdate(prevDeps: DependencyList | undefined, newDeps: DependencyList | undefined, parentBlocked: boolean): boolean;
|
|
101
|
+
/**
|
|
102
|
+
* The core normalization function for a single child. It takes any valid `NodeElement`
|
|
103
|
+
* (primitive, React element, function, `BaseNode` instance) and converts it into a standardized `BaseNode`
|
|
104
|
+
* instance if it isn't one already. This ensures a consistent structure for the iterative renderer.
|
|
105
|
+
* @method processRawNode
|
|
106
|
+
*/
|
|
107
|
+
static processRawNode(node: NodeElement, disableEmotion?: boolean, stableKey?: string): NodeElement;
|
|
108
|
+
/**
|
|
109
|
+
* A helper to reliably identify if a given function is a "function-as-a-child" (render prop)
|
|
110
|
+
* rather than a standard Function Component.
|
|
111
|
+
* @method isFunctionChild
|
|
112
|
+
*/
|
|
113
|
+
static isFunctionChild<E extends NodeInstance | ReactNode>(node: NodeElement): node is NodeFunction<E>;
|
|
114
|
+
/**
|
|
115
|
+
* A special internal React component used to render "function-as-a-child" (render prop) patterns.
|
|
116
|
+
* When a `BaseNode` receives a function as its `children` prop, it wraps that function
|
|
117
|
+
* inside this `functionRenderer` component. This component then executes the render function
|
|
118
|
+
* and processes its return value, normalizing it into a renderable ReactNode.
|
|
119
|
+
*
|
|
120
|
+
* This allows `BaseNode` to support render props while maintaining its internal processing
|
|
121
|
+
* and normalization logic for the dynamically generated content.
|
|
122
|
+
* @method functionRenderer
|
|
123
|
+
* @param {Object} props The properties passed to the renderer.
|
|
124
|
+
* @param {Function} props.render The function-as-a-child to execute.
|
|
125
|
+
* @param {boolean} [props.disableEmotion] Inherited flag to disable Emotion styling for children.
|
|
126
|
+
* @returns {ReactNode | null | undefined} The processed and rendered output of the render function.
|
|
127
|
+
*/
|
|
128
|
+
static functionRenderer<E extends ReactNode | NodeInstance>({ render, disableEmotion }: FunctionRendererProps<E>): ReactNode | null | undefined;
|
|
129
|
+
/**
|
|
130
|
+
* Renders a processed `NodeElement` into a ReactNode.
|
|
131
|
+
* This helper is primarily used by `functionRenderer` to handle the output of render props,
|
|
132
|
+
* ensuring that `BaseNode` instances are correctly rendered and other React elements or primitives
|
|
133
|
+
* are passed through. It also applies `disableEmotion` and `key` props as needed.
|
|
134
|
+
*
|
|
135
|
+
* This method is part of the child processing pipeline, converting internal `NodeElement` representations
|
|
136
|
+
* into actual React elements that can be rendered by React.
|
|
137
|
+
* @method renderProcessedNode
|
|
138
|
+
*/
|
|
139
|
+
static renderProcessedNode({ processedElement, passedKey, disableEmotion }: {
|
|
140
|
+
processedElement: NodeElement;
|
|
141
|
+
passedKey?: string;
|
|
142
|
+
disableEmotion?: boolean;
|
|
143
|
+
}): string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | Iterable<ReactNode> | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | React.ReactPortal | null | undefined> | React.ReactElement<any, string | React.JSXElementConstructor<any>> | null | undefined;
|
|
144
|
+
/**
|
|
145
|
+
* Ensures that the necessary DOM element and React root are available for portal rendering.
|
|
146
|
+
* This is only executed on the client-side.
|
|
147
|
+
* @method ensurePortalInfrastructure
|
|
148
|
+
*/
|
|
149
|
+
static ensurePortalInfrastructure(node: NodeInstance): boolean;
|
|
150
|
+
static cleanupPortalInfra(infra: {
|
|
151
|
+
domElement: HTMLDivElement;
|
|
152
|
+
reactRoot: any;
|
|
153
|
+
}): void;
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=node.util.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.util.d.ts","sourceRoot":"","sources":["../../src/util/node.util.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAyC,KAAK,SAAS,EAAiC,MAAM,OAAO,CAAA;AACnH,OAAO,KAAK,EACV,qBAAqB,EACrB,WAAW,EACX,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,SAAS,EACT,cAAc,EACd,UAAU,EACV,cAAc,EAEf,MAAM,yBAAyB,CAAA;AAOhC;;;;;GAKG;AACH,qBAAa,QAAQ;IACnB,OAAO,eAAiB;IAGxB,OAAc,QAAQ,UAAgC;IAGtD,OAAO,CAAC,MAAM,CAAC,uBAAuB,CAAgC;IAGtE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,OAAM;IAC9C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,MAAK;IAGhD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,sBAAsB,CAAkC;IAChF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAA2D;IAGjG,OAAc,oBAAoB;;;;;OAM/B;IAEH;;;;;;;;;;OAUG;IACH,OAAc,cAAc,wCAS3B;IAED;;;;;OAKG;IACH,OAAc,WAAW,yBAAgH;IAEzI;;;OAGG;IACH,OAAc,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAc5C;IAED;;;OAGG;IACH,OAAc,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAclF;IAED;;;;;OAKG;IACH,OAAc,mBAAmB,CAAC,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,GAAG,SAAS,CAoD1G;IAED;;;;;;OAMG;IACH,OAAc,oBAAoB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAclG;IAED;;;;OAIG;IACH,OAAc,iBAAiB,CAAC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;KAAE,CAyC1H;IAED;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAyB/B;;;;OAIG;IACH,OAAc,YAAY,CAAC,OAAO,EAAE,eAAe,EAAE,QAAQ,GAAE,OAAO,CAAC,SAAS,CAAC,eAAe,CAAC,CAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,cAAc,CAuD3I;IAED;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAQ/B;;;;OAIG;IACH,OAAc,gBAAgB,CAAC,QAAQ,EAAE,cAAc,GAAG,SAAS,EAAE,OAAO,EAAE,cAAc,GAAG,SAAS,EAAE,aAAa,EAAE,OAAO,GAAG,OAAO,CA4BzI;IAED;;;;;OAKG;IACH,OAAc,cAAc,CAAC,IAAI,EAAE,WAAW,EAAE,cAAc,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,WAAW,CAsDzG;IAED;;;;OAIG;IACH,OAAc,eAAe,CAAC,CAAC,SAAS,YAAY,GAAG,SAAS,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,IAAI,YAAY,CAAC,CAAC,CAAC,CAU5G;IAED;;;;;;;;;;;;;OAaG;IACH,OAAc,gBAAgB,CAAC,CAAC,SAAS,SAAS,GAAG,YAAY,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAAG,SAAS,GAAG,IAAI,GAAG,SAAS,CA0DrJ;IAED;;;;;;;;;OASG;IACH,OAAc,mBAAmB,CAAC,EAChC,gBAAgB,EAChB,SAAS,EACT,cAAc,EACf,EAAE;QACD,gBAAgB,EAAE,WAAW,CAAA;QAC7B,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,cAAc,CAAC,EAAE,OAAO,CAAA;KACzB,wUA8BA;IAED;;;;OAIG;IACH,OAAc,0BAA0B,CAAC,IAAI,EAAE,YAAY,WA0C1D;IAED,OAAc,kBAAkB,CAAC,KAAK,EAAE;QAAE,UAAU,EAAE,cAAc,CAAC;QAAC,SAAS,EAAE,GAAG,CAAA;KAAE,QAgBrF;CACF"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
var _NodeUtil,_excluded=["ref","key","children","css","props","disableEmotion"],_excluded2=["style"];function ownKeys(a,b){var c=Object.keys(a);if(Object.getOwnPropertySymbols){var d=Object.getOwnPropertySymbols(a);b&&(d=d.filter(function(b){return Object.getOwnPropertyDescriptor(a,b).enumerable})),c.push.apply(c,d)}return c}function _objectSpread(a){for(var b,c=1;c<arguments.length;c++)b=null==arguments[c]?{}:arguments[c],c%2?ownKeys(Object(b),!0).forEach(function(c){_defineProperty(a,c,b[c])}):Object.getOwnPropertyDescriptors?Object.defineProperties(a,Object.getOwnPropertyDescriptors(b)):ownKeys(Object(b)).forEach(function(c){Object.defineProperty(a,c,Object.getOwnPropertyDescriptor(b,c))});return a}function _objectWithoutProperties(a,b){if(null==a)return{};var c,d,e=_objectWithoutPropertiesLoose(a,b);if(Object.getOwnPropertySymbols){var f=Object.getOwnPropertySymbols(a);for(d=0;d<f.length;d++)c=f[d],-1===b.indexOf(c)&&{}.propertyIsEnumerable.call(a,c)&&(e[c]=a[c])}return e}function _objectWithoutPropertiesLoose(a,b){if(null==a)return{};var c={};for(var d in a)if({}.hasOwnProperty.call(a,d)){if(-1!==b.indexOf(d))continue;c[d]=a[d]}return c}function _slicedToArray(a,b){return _arrayWithHoles(a)||_iterableToArrayLimit(a,b)||_unsupportedIterableToArray(a,b)||_nonIterableRest()}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _iterableToArrayLimit(b,c){var d=null==b?null:"undefined"!=typeof Symbol&&b[Symbol.iterator]||b["@@iterator"];if(null!=d){var g,h,j,k,l=[],a=!0,m=!1;try{if(j=(d=d.call(b)).next,0===c){if(Object(d)!==d)return;a=!1}else for(;!(a=(g=j.call(d)).done)&&(l.push(g.value),l.length!==c);a=!0);}catch(a){m=!0,h=a}finally{try{if(!a&&null!=d["return"]&&(k=d["return"](),Object(k)!==k))return}finally{if(m)throw h}}return l}}function _arrayWithHoles(a){if(Array.isArray(a))return a}function _typeof(a){"@babel/helpers - typeof";return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},_typeof(a)}function _createForOfIteratorHelper(b,c){var d="undefined"!=typeof Symbol&&b[Symbol.iterator]||b["@@iterator"];if(!d){if(Array.isArray(b)||(d=_unsupportedIterableToArray(b))||c&&b&&"number"==typeof b.length){d&&(b=d);var e=0,f=function F(){};return{s:f,n:function n(){return e>=b.length?{done:!0}:{done:!1,value:b[e++]}},e:function e(a){throw a},f:f}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var g,h=!0,i=!1;return{s:function s(){d=d.call(b)},n:function n(){var a=d.next();return h=a.done,a},e:function e(a){i=!0,g=a},f:function f(){try{h||null==d["return"]||d["return"]()}finally{if(i)throw g}}}}function _unsupportedIterableToArray(b,c){if(b){if("string"==typeof b)return _arrayLikeToArray(b,c);var a={}.toString.call(b).slice(8,-1);return"Object"===a&&b.constructor&&(a=b.constructor.name),"Map"===a||"Set"===a?Array.from(b):"Arguments"===a||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(a)?_arrayLikeToArray(b,c):void 0}}function _arrayLikeToArray(b,c){(null==c||c>b.length)&&(c=b.length);for(var d=0,f=Array(c);d<c;d++)f[d]=b[d];return f}function _defineProperty(a,b,c){return(b=_toPropertyKey(b))in a?Object.defineProperty(a,b,{value:c,enumerable:!0,configurable:!0,writable:!0}):a[b]=c,a}function _toPropertyKey(a){var b=_toPrimitive(a,"string");return"symbol"==_typeof(b)?b:b+""}function _toPrimitive(a,b){if("object"!=_typeof(a)||!a)return a;var c=a[Symbol.toPrimitive];if(void 0!==c){var d=c.call(a,b||"default");if("object"!=_typeof(d))return d;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===b?String:Number)(a)}import React,{createElement,isValidElement}from"react";import{isForwardRef,isMemo,isReactClassComponent}from"../helper/react-is.helper.js";import{getCSSProps,getDOMProps,getElementTypeName,omitUndefined}from"../helper/common.helper.js";import{__DEBUG__}from"../constants/common.const.js";import{BaseNode}from"../core.node.js";import{createRoot}from"react-dom/client";/**
|
|
2
|
+
* NodeUtil provides a collection of static utility methods and properties
|
|
3
|
+
* used internally by BaseNode for various tasks such as hashing, shallow comparison,
|
|
4
|
+
* and stable element ID generation. This centralizes common helper functions,
|
|
5
|
+
* improving modularity and maintainability of the core library.
|
|
6
|
+
*/export class NodeUtil{constructor(){}// Determines if the current environment is server-side (Node.js) or client-side (browser).
|
|
7
|
+
/**
|
|
8
|
+
* Combines FNV-1a and djb2 hash functions for a more robust signature.
|
|
9
|
+
* @method hashString
|
|
10
|
+
*/static hashString(a){// FNV offset basis
|
|
11
|
+
// djb2 init
|
|
12
|
+
for(var b=Math.imul,c,d=2166136261,e=5381,f=0;f<a.length;f++)// FNV-1a
|
|
13
|
+
// djb2
|
|
14
|
+
c=a.charCodeAt(f),d^=c,d=b(d,16777619),e=33*e^c;return"".concat((d>>>0).toString(36),"_").concat((e>>>0).toString(36))}/**
|
|
15
|
+
* Performs a shallow equality check between two objects.
|
|
16
|
+
* @method shallowEqual
|
|
17
|
+
*/static shallowEqual(c,a){if(c===a)return!0;var b=0,d=0;for(var e in c){if(!(e in a)||c[e]!==a[e])return!1;b++}for(var f in a)d++;return b===d}/**
|
|
18
|
+
* Creates a unique, stable signature from the element type and props.
|
|
19
|
+
* This signature includes the element's type to prevent collisions between different components
|
|
20
|
+
* and handles primitive values in arrays and objects for better caching.
|
|
21
|
+
* @method createPropSignature
|
|
22
|
+
*/static createPropSignature(a,b){if(!NodeUtil.isServer){var c=getElementTypeName(a),d=Object.keys(b).sort(),e=["".concat(c,":")];if("function"==typeof a){var f=NodeUtil._functionSignatureCache.get(a);f||(f=NodeUtil.hashString(a.toString()),NodeUtil._functionSignatureCache.set(a,f)),e.push(f)}var g,h=_createForOfIteratorHelper(d);try{for(h.s();!(g=h.n()).done;){var i=g.value,j=b[i],k=void 0,l=_typeof(j);if("string"===l||"number"===l||"boolean"===l)k="".concat(i,":").concat(j,";");else if(null===j)k="".concat(i,":null;");else if(void 0===j)k="".concat(i,":undefined;");else if(Array.isArray(j)){// Hash primitive values in arrays for better cache hits
|
|
23
|
+
var m=j.filter(function(a){var b=_typeof(a);return"string"===b||"number"===b||"boolean"===b||null===a});k=m.length===j.length?"".concat(i,":[").concat(m.join(","),"];"):"".concat(i,":[").concat(j.length,"];")}else if(j&&j.isBaseNode)k="".concat(i,":").concat(j.stableKey,";");else{// Include sorted keys for object structure signature
|
|
24
|
+
var n=Object.keys(j).sort();k="".concat(i,":{").concat(n.join(","),"};")}e.push(k)}}catch(a){h.e(a)}finally{h.f()}return NodeUtil.hashString(e.join(","))}}/**
|
|
25
|
+
* Extracts "critical" props from a given set of props. Critical props are those
|
|
26
|
+
* that are frequently used for styling or event handling, such as `on*` handlers,
|
|
27
|
+
* `aria-*` attributes, `data-*` attributes, `css`, `className`, and `style`.
|
|
28
|
+
* This method is used to optimize prop processing by focusing on props that are
|
|
29
|
+
* most likely to influence rendering or behavior.
|
|
30
|
+
*/static extractCriticalProps(a,b){var c,d={_keyCount:b.length},e=0,f=_createForOfIteratorHelper(b);try{var g=function _loop(){var b=c.value;return 50<=e?1:void((NodeUtil.CRITICAL_PROPS.has(b)||NodeUtil.isStyleProp(b)||Array.from(NodeUtil.CRITICAL_PROP_PREFIXES).some(function(a){return b.startsWith(a)}))&&(d[b]=a[b],e++))};for(f.s();!(c=f.n()).done&&!g(););}catch(a){f.e(a)}finally{f.f()}return d}/**
|
|
31
|
+
* Retrieves computed CSS props from the cache with LRU tracking.
|
|
32
|
+
* Access time and hit count are tracked for smarter eviction.
|
|
33
|
+
* @method getCachedCssProps
|
|
34
|
+
*/static getCachedCssProps(a,b){if(NodeUtil.isServer||!b)return{cssProps:getCSSProps(a)};var c=BaseNode.propProcessingCache.get(b);if(c)return c.lastAccess=Date.now(),c.hitCount++,{cssProps:c.cssProps};var d=getCSSProps(a);return BaseNode.propProcessingCache.set(b,{cssProps:d,signature:b,lastAccess:Date.now(),hitCount:1}),BaseNode.propProcessingCache.size>NodeUtil.CACHE_SIZE_LIMIT&&!BaseNode.scheduledCleanup&&(BaseNode.scheduledCleanup=!0,"undefined"==typeof requestIdleCallback?setTimeout(function(){NodeUtil._evictLRUEntries(),BaseNode.scheduledCleanup=!1},100):requestIdleCallback(function(){NodeUtil._evictLRUEntries(),BaseNode.scheduledCleanup=!1},{timeout:2e3})),{cssProps:d}}/**
|
|
35
|
+
* Implements an LRU eviction strategy that removes multiple entries at once.
|
|
36
|
+
* It uses a scoring system where older and less frequently used entries have a higher eviction priority.
|
|
37
|
+
* @method _evictLRUEntries
|
|
38
|
+
*/static _evictLRUEntries(){var a,b=Date.now(),c=[],d=_createForOfIteratorHelper(BaseNode.propProcessingCache.entries());// Calculate eviction scores for all entries
|
|
39
|
+
try{for(d.s();!(a=d.n()).done;){var e=_slicedToArray(a.value,2),f=e[0],g=e[1],h=b-g.lastAccess,j=g.hitCount,k=h/1e3+1e3/(j+1);// Score: older age + lower frequency = higher score (more likely to evict)
|
|
40
|
+
// Normalize: age in seconds, frequency as inverse
|
|
41
|
+
c.push({key:f,score:k})}// Sort by score (highest = most evictable)
|
|
42
|
+
}catch(a){d.e(a)}finally{d.f()}c.sort(function(c,a){return a.score-c.score});// Remove top N entries
|
|
43
|
+
for(var l=Math.min(NodeUtil.CACHE_CLEANUP_BATCH,c.length),m=0;m<l;m++)BaseNode.propProcessingCache["delete"](c[m].key)}/**
|
|
44
|
+
* The main prop processing pipeline. It separates cacheable and non-cacheable props,
|
|
45
|
+
* generates a signature for caching, and assembles the final props object.
|
|
46
|
+
* @method processProps
|
|
47
|
+
*/static processProps(a){var b=1<arguments.length&&arguments[1]!==void 0?arguments[1]:{},c=2<arguments.length?arguments[2]:void 0,d=b.ref,e=b.key,f=b.children,g=b.css,h=b.props,i=void 0===h?{}:h,j=b.disableEmotion,k=_objectWithoutProperties(b,_excluded);// --- Fast Path Optimization ---
|
|
48
|
+
if(0===Object.keys(k).length&&!g)return omitUndefined({ref:d,key:e,disableEmotion:j,nativeProps:omitUndefined(i),children:NodeUtil._processChildren(f,j)});// --- Hybrid Caching Strategy ---
|
|
49
|
+
var l={},m={};// 1. Categorize props into cacheable (primitives) and non-cacheable (objects/functions).
|
|
50
|
+
for(var n in k)if(Object.prototype.hasOwnProperty.call(k,n)){var o=k[n],p=_typeof(o);"string"===p||"number"===p||"boolean"===p?l[n]=o:m[n]=o}// 2. Pass element type to signature generation
|
|
51
|
+
var q=NodeUtil.createPropSignature(a,l),r=NodeUtil.getCachedCssProps(l,q),s=r.cssProps,t=getCSSProps(m),u=getDOMProps(k),v=_objectSpread(_objectSpread(_objectSpread({},s),t),g),w=NodeUtil._processChildren(f,j,c);// 3. Process non-cacheable props on every render to ensure correctness for functions and objects.
|
|
52
|
+
// DOM props are always processed fresh.
|
|
53
|
+
// 4. Assemble the final CSS object.
|
|
54
|
+
// --- Child Normalization ---
|
|
55
|
+
// --- Final Assembly ---
|
|
56
|
+
return omitUndefined(_objectSpread(_objectSpread({ref:d,key:e,css:v},u),{},{disableEmotion:j,nativeProps:omitUndefined(i),children:w}))}/**
|
|
57
|
+
* Processes and normalizes children of the node.
|
|
58
|
+
* Converts raw children (React elements, primitives, or other BaseNodes) into a consistent format.
|
|
59
|
+
* @param children The raw children to process.
|
|
60
|
+
* @param disableEmotion If true, emotion styling will be disabled for these children.
|
|
61
|
+
* @param parentStableKey The stable key of the parent node, used for generating unique keys for children.
|
|
62
|
+
*/static _processChildren(a,b,c){return a?"function"==typeof a?a:Array.isArray(a)?a.map(function(a,d){return NodeUtil.processRawNode(a,b,"".concat(c,"_").concat(d))}):NodeUtil.processRawNode(a,b,c):void 0}/**
|
|
63
|
+
* Determines if a node should update based on its dependency array.
|
|
64
|
+
* Uses a shallow comparison, similar to React's `useMemo` and `useCallback`.
|
|
65
|
+
* @method shouldNodeUpdate
|
|
66
|
+
*/static shouldNodeUpdate(a,b,c){// SSR has no concept of re-renders, so deps system doesn't apply
|
|
67
|
+
return!!NodeUtil.isServer||!c&&(!(void 0!==b)||!(void 0!==a)||b.length!==a.length||!!b.some(function(b,c){return!Object.is(b,a[c])}));// No deps array means always update.
|
|
68
|
+
// First render for this keyed component, or no previous deps.
|
|
69
|
+
// Length change means update.
|
|
70
|
+
// Shallow compare deps. If any have changed, update.
|
|
71
|
+
// Deps are the same, no update needed.
|
|
72
|
+
}/**
|
|
73
|
+
* The core normalization function for a single child. It takes any valid `NodeElement`
|
|
74
|
+
* (primitive, React element, function, `BaseNode` instance) and converts it into a standardized `BaseNode`
|
|
75
|
+
* instance if it isn't one already. This ensures a consistent structure for the iterative renderer.
|
|
76
|
+
* @method processRawNode
|
|
77
|
+
*/static processRawNode(a,b,c){// Primitives and null/undefined are returned as-is.
|
|
78
|
+
if(null===a||a===void 0||"string"==typeof a||"number"==typeof a||"boolean"==typeof a)return a;// If it's already a BaseNode, clone it with a positional key if available.
|
|
79
|
+
if(NodeUtil.isNodeInstance(a)){var d=c||b&&!a.rawProps.disableEmotion;if(d){// Create a new BaseNode instance.
|
|
80
|
+
var e=new BaseNode(a.element,a.rawProps,a.dependencies);// Augment the internal stableKey with positional information.
|
|
81
|
+
// This is purely for BaseNode's internal caching, not for React's 'key' prop.
|
|
82
|
+
return e.stableKey="".concat(c,":").concat(e.stableKey),b&&!e.rawProps.disableEmotion&&(e.rawProps.disableEmotion=!0),e}return a}// Handle function-as-a-child (render props).
|
|
83
|
+
if(NodeUtil.isFunctionChild(a))return new BaseNode(NodeUtil.functionRenderer,{props:{render:a,disableEmotion:b}},void 0);// Handle standard React elements.
|
|
84
|
+
if(isValidElement(a)){var f=a.props,g=f.style,h=_objectWithoutProperties(f,_excluded2),i=_objectSpread(_objectSpread({},h),g||{});return new BaseNode(a.type,_objectSpread(_objectSpread(_objectSpread({},i),null!==a.key&&void 0!==a.key?{key:a.key}:{}),{},{disableEmotion:b}),void 0)}// Handle component classes and memos.
|
|
85
|
+
return isReactClassComponent(a)||isMemo(a)||isForwardRef(a)?new BaseNode(a,{disableEmotion:b},void 0):a instanceof React.Component?NodeUtil.processRawNode(a.render(),b,c):a;// Handle component instances.
|
|
86
|
+
}/**
|
|
87
|
+
* A helper to reliably identify if a given function is a "function-as-a-child" (render prop)
|
|
88
|
+
* rather than a standard Function Component.
|
|
89
|
+
* @method isFunctionChild
|
|
90
|
+
*/static isFunctionChild(a){if("function"!=typeof a||isReactClassComponent(a)||isMemo(a)||isForwardRef(a))return!1;try{return!(a.prototype&&"function"==typeof a.prototype.render)}catch(a){return __DEBUG__&&console.error("MeoNode: Error checking if a node is a function child.",a),!0}}/**
|
|
91
|
+
* A special internal React component used to render "function-as-a-child" (render prop) patterns.
|
|
92
|
+
* When a `BaseNode` receives a function as its `children` prop, it wraps that function
|
|
93
|
+
* inside this `functionRenderer` component. This component then executes the render function
|
|
94
|
+
* and processes its return value, normalizing it into a renderable ReactNode.
|
|
95
|
+
*
|
|
96
|
+
* This allows `BaseNode` to support render props while maintaining its internal processing
|
|
97
|
+
* and normalization logic for the dynamically generated content.
|
|
98
|
+
* @method functionRenderer
|
|
99
|
+
* @param {Object} props The properties passed to the renderer.
|
|
100
|
+
* @param {Function} props.render The function-as-a-child to execute.
|
|
101
|
+
* @param {boolean} [props.disableEmotion] Inherited flag to disable Emotion styling for children.
|
|
102
|
+
* @returns {ReactNode | null | undefined} The processed and rendered output of the render function.
|
|
103
|
+
*/static functionRenderer(a){var b,c=a.render,d=a.disableEmotion;try{// Execute the render prop function to get its output.
|
|
104
|
+
b=c()}catch(a){// If the render function throws, treat its output as null to prevent crashes.
|
|
105
|
+
__DEBUG__&&console.error("MeoNode: Error executing function-as-a-child.",a),b=null}// Handle null or undefined results directly, as they are valid React render outputs.
|
|
106
|
+
if(null===b||b===void 0)return b;// If the result is already a BaseNode instance, process it.
|
|
107
|
+
if(NodeUtil.isNodeInstance(b))// If emotion is disabled for the parent and not explicitly re-enabled on the child,
|
|
108
|
+
// create a new BaseNode with emotion disabled and render it.
|
|
109
|
+
return d&&!b.rawProps.disableEmotion?new BaseNode(b.element,_objectSpread(_objectSpread({},b.rawProps),{},{disableEmotion:!0})).render():b.render();// Otherwise, render the existing BaseNode directly.
|
|
110
|
+
// If the result is an array, it likely contains multiple children.
|
|
111
|
+
if(Array.isArray(b)){// Helper to generate a stable key for array items, crucial for React's reconciliation.
|
|
112
|
+
var e=function safeGetKey(a,b){try{// Attempt to get a meaningful name for the element type.
|
|
113
|
+
return"".concat(getElementTypeName(a),"-").concat(b)}catch(a){// Fallback to a generic key if type name cannot be determined.
|
|
114
|
+
return __DEBUG__&&console.error("MeoNode: Could not determine element type name for key in function-as-a-child.",a),"item-".concat(b)}};// Map over the array, processing each item and assigning a key.
|
|
115
|
+
return b.map(function(a,b){return NodeUtil.renderProcessedNode({processedElement:NodeUtil.processRawNode(a,d),passedKey:e(a,b),disableEmotion:d})})}if(b instanceof React.Component)return NodeUtil.renderProcessedNode({processedElement:NodeUtil.processRawNode(b.render(),d),disableEmotion:d});// Handle primitive types directly, as they are valid React children.
|
|
116
|
+
if("string"==typeof b||"number"==typeof b||"boolean"==typeof b)return b;// For any other non-primitive, non-array result, process it as a single NodeElement.
|
|
117
|
+
var f=NodeUtil.processRawNode(b,d);// If processing yields a valid element, render it.
|
|
118
|
+
return f?NodeUtil.renderProcessedNode({processedElement:f,disableEmotion:d}):b;// Fallback: return the original result if it couldn't be processed into a renderable node.
|
|
119
|
+
}/**
|
|
120
|
+
* Renders a processed `NodeElement` into a ReactNode.
|
|
121
|
+
* This helper is primarily used by `functionRenderer` to handle the output of render props,
|
|
122
|
+
* ensuring that `BaseNode` instances are correctly rendered and other React elements or primitives
|
|
123
|
+
* are passed through. It also applies `disableEmotion` and `key` props as needed.
|
|
124
|
+
*
|
|
125
|
+
* This method is part of the child processing pipeline, converting internal `NodeElement` representations
|
|
126
|
+
* into actual React elements that can be rendered by React.
|
|
127
|
+
* @method renderProcessedNode
|
|
128
|
+
*/static renderProcessedNode(a){var b=a.processedElement,c=a.passedKey,d=a.disableEmotion,e={};// Initialize an object to hold common props that might be applied to the new BaseNode.
|
|
129
|
+
// If a `passedKey` is provided, add it to `commonBaseNodeProps`.
|
|
130
|
+
// This key is typically used for React's reconciliation process.
|
|
131
|
+
// If the processed element is already a BaseNode instance.
|
|
132
|
+
if(void 0!==c&&(e.key=c),NodeUtil.isNodeInstance(b)){var f,g=null===(f=b.rawProps)||void 0===f?void 0:f.key;// Get the existing key from the raw props of the BaseNode.
|
|
133
|
+
// Apply the `disableEmotion` flag to the raw props of the BaseNode.
|
|
134
|
+
// If the existing key is the same as the passed key, render the existing BaseNode directly.
|
|
135
|
+
// This avoids unnecessary re-creation of the BaseNode instance.
|
|
136
|
+
return b.rawProps.disableEmotion=d,g===c?b.render():new BaseNode(b.element,_objectSpread(_objectSpread({},b.rawProps),e)).render();// Otherwise, create a new BaseNode instance, merging existing raw props with common props, then render it.
|
|
137
|
+
}// If the processed element is a React class component (e.g., `class MyComponent extends React.Component`).
|
|
138
|
+
// Create a new BaseNode for it, applying common props and `disableEmotion`, then render.
|
|
139
|
+
return isReactClassComponent(b)?new BaseNode(b,_objectSpread(_objectSpread({},e),{},{disableEmotion:d})).render():b instanceof React.Component?b.render():"function"==typeof b?createElement(b,{key:c}):b;// If the processed element is an instance of a React component (e.g., `new MyComponent()`).
|
|
140
|
+
// Directly call its `render` method.
|
|
141
|
+
// If the processed element is a function (likely a functional component or a render prop that returned a component type).
|
|
142
|
+
// Create a React element directly using `createElement`, passing the `passedKey`.
|
|
143
|
+
// For any other type (primitives, null, undefined, etc.), return it as a ReactNode.
|
|
144
|
+
}/**
|
|
145
|
+
* Ensures that the necessary DOM element and React root are available for portal rendering.
|
|
146
|
+
* This is only executed on the client-side.
|
|
147
|
+
* @method ensurePortalInfrastructure
|
|
148
|
+
*/static ensurePortalInfrastructure(a){var b,c,d;if(NodeUtil.isServer)return!1;var e=NodeUtil.portalInfrastructure.get(a);// Check if infrastructure exists and is still connected
|
|
149
|
+
if(null!==(b=e)&&void 0!==b&&null!==(b=b.domElement)&&void 0!==b&&b.isConnected&&null!==(c=e)&&void 0!==c&&c.reactRoot)return!0;// Clean up stale or disconnected infrastructure
|
|
150
|
+
if(e&&(!(null!==(d=e.domElement)&&void 0!==d&&d.isConnected)||!e.reactRoot)){try{var f,g;null===(f=e.reactRoot)||void 0===f||null===(g=f.unmount)||void 0===g||g.call(f)}catch(a){__DEBUG__&&console.error("MeoNode: Error unmounting stale portal root.",a)}NodeUtil.cleanupPortalInfra(e),NodeUtil.portalInfrastructure["delete"](a),e=void 0}// Create new infrastructure
|
|
151
|
+
var h=document.createElement("div");document.body.appendChild(h);var i=createRoot(h),j={render:i.render.bind(i),unmount:i.unmount.bind(i),update:function update(){}// Placeholder, will be overridden
|
|
152
|
+
};return e={domElement:h,reactRoot:j},NodeUtil.portalInfrastructure.set(a,e),BaseNode.portalCleanupRegistry.register(a,{domElement:h,reactRoot:j},a),!0}static cleanupPortalInfra(a){try{var b;null!==(b=a.reactRoot)&&void 0!==b&&b.unmount&&a.reactRoot.unmount()}catch(a){__DEBUG__&&console.error("Portal cleanup error:",a)}try{var c;null!==(c=a.domElement)&&void 0!==c&&c.isConnected&&a.domElement.remove()}catch(a){__DEBUG__&&console.error("DOM removal error:",a)}}}// Unique ID generation for elements
|
|
153
|
+
// Cache configuration
|
|
154
|
+
// Clean up 50 entries at once when limit hit
|
|
155
|
+
// Critical props for signature generation and shallow comparison
|
|
156
|
+
// Portal infrastructure using WeakMap for memory-safe management
|
|
157
|
+
/**
|
|
158
|
+
* Type guard to check if an object is a NodeInstance.
|
|
159
|
+
*
|
|
160
|
+
* A NodeInstance is expected to be a non-null object with:
|
|
161
|
+
* - an 'element' property,
|
|
162
|
+
* - a 'render' method,
|
|
163
|
+
* - a 'toPortal' method,
|
|
164
|
+
* - and an 'isBaseNode' property.
|
|
165
|
+
* @param obj The object to check.
|
|
166
|
+
* @returns True if the object is a NodeInstance, false otherwise.
|
|
167
|
+
*//**
|
|
168
|
+
* Determines if a given string `k` is a valid CSS style property.
|
|
169
|
+
* This check is performed only on the client-side by checking if the property exists in `document.body.style`.
|
|
170
|
+
* On the server-side, it always returns `false`.
|
|
171
|
+
* @param k The string to check.
|
|
172
|
+
*/_NodeUtil=NodeUtil,_defineProperty(NodeUtil,"isServer","undefined"==typeof window),_defineProperty(NodeUtil,"_functionSignatureCache",new WeakMap),_defineProperty(NodeUtil,"CACHE_SIZE_LIMIT",500),_defineProperty(NodeUtil,"CACHE_CLEANUP_BATCH",50),_defineProperty(NodeUtil,"CRITICAL_PROP_PREFIXES",new Set(["on","aria","data"])),_defineProperty(NodeUtil,"CRITICAL_PROPS",new Set(["css","className","disableEmotion","props"])),_defineProperty(NodeUtil,"portalInfrastructure",new WeakMap),_defineProperty(NodeUtil,"isNodeInstance",function(a){return"object"===_typeof(a)&&null!==a&&"element"in a&&"function"==typeof a.render&&"function"==typeof a.toPortal&&"isBaseNode"in a}),_defineProperty(NodeUtil,"isStyleProp",_NodeUtil.isServer||"undefined"==typeof document?function(){return!1}:function(a){return a in document.body.style});
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import type { CSSInterpolation, CSSProperties } from '@emotion/serialize';
|
|
2
|
+
import type { Theme } from '../types/node.type.js';
|
|
3
|
+
/**
|
|
4
|
+
* Parsed flex shorthand components for CSS flex property
|
|
5
|
+
* @interface FlexComponents
|
|
6
|
+
* @property grow - The flex-grow value (how much the item should grow)
|
|
7
|
+
* @property shrink - The flex-shrink value (how much the item should shrink)
|
|
8
|
+
* @property basis - The flex-basis value (initial main size before free space is distributed)
|
|
9
|
+
*/
|
|
10
|
+
interface FlexComponents {
|
|
11
|
+
grow: number;
|
|
12
|
+
shrink: number;
|
|
13
|
+
basis: string | number;
|
|
14
|
+
}
|
|
15
|
+
export declare class ThemeUtil {
|
|
16
|
+
private constructor();
|
|
17
|
+
private static themeCache;
|
|
18
|
+
/**
|
|
19
|
+
* Parses a CSS flex shorthand property into its individual components.
|
|
20
|
+
*
|
|
21
|
+
* The CSS flex property is a shorthand for flex-grow, flex-shrink, and flex-basis.
|
|
22
|
+
* This parser handles the most common flex shorthand patterns to extract the shrink value
|
|
23
|
+
* when it's explicitly set by the user.
|
|
24
|
+
*
|
|
25
|
+
* Supported patterns:
|
|
26
|
+
* - Keywords: 'none' | 'auto' | 'initial'
|
|
27
|
+
* - Single number: '1' → {grow: 1, shrink: 1, basis: '0%'}
|
|
28
|
+
* - Full shorthand: '1 0 auto' → {grow: 1, shrink: 0, basis: 'auto'}
|
|
29
|
+
* @param flex The CSS flex property value to parse
|
|
30
|
+
* @returns FlexComponents object with parsed values, or null if unparseable
|
|
31
|
+
* @example
|
|
32
|
+
* parseFlexShorthand('none') // → {grow: 0, shrink: 0, basis: 'auto'}
|
|
33
|
+
* parseFlexShorthand('1') // → {grow: 1, shrink: 1, basis: '0%'}
|
|
34
|
+
* parseFlexShorthand('1 0 auto') // → {grow: 1, shrink: 0, basis: 'auto'}
|
|
35
|
+
*/
|
|
36
|
+
static parseFlexShorthand(flex: CSSProperties['flex']): FlexComponents | null;
|
|
37
|
+
static isPlainObject: (value: any) => boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Resolves theme variable references in an object's values iteratively.
|
|
40
|
+
* This function uses a manual work stack to traverse the object, which prevents
|
|
41
|
+
* "Maximum call stack size exceeded" errors for deeply nested objects.
|
|
42
|
+
* It performs a "smart merge" by using a copy-on-write strategy, creating new
|
|
43
|
+
* objects/arrays only when a value inside them has changed. This preserves
|
|
44
|
+
* object references for unchanged parts of the tree, which is critical for
|
|
45
|
+
* React's reconciliation and memoization.
|
|
46
|
+
*/
|
|
47
|
+
static resolveObjWithTheme: (obj?: Record<string, any>, theme?: Theme | undefined, options?: {
|
|
48
|
+
processFunctions?: boolean | undefined;
|
|
49
|
+
}) => any;
|
|
50
|
+
static clearThemeCache: () => void;
|
|
51
|
+
/**
|
|
52
|
+
* Resolves default CSS styles to fix common flexbox layout issues.
|
|
53
|
+
*
|
|
54
|
+
* PRIMARY PURPOSE: Fix the flexbox scrolling problem
|
|
55
|
+
* ================================================
|
|
56
|
+
*
|
|
57
|
+
* THE PROBLEM:
|
|
58
|
+
* By default, flex items have `min-width: auto` and `min-height: auto`, which means they
|
|
59
|
+
* cannot shrink below their content size. This prevents scrollable containers from working
|
|
60
|
+
* properly when they are flex items.
|
|
61
|
+
*
|
|
62
|
+
* THE SOLUTION:
|
|
63
|
+
* 1. Set `minHeight: 0` and `minWidth: 0` to allow flex items to shrink
|
|
64
|
+
* 2. Control `flexShrink` behavior based on context to prevent unwanted shrinking
|
|
65
|
+
* 3. Respect user's explicit values to avoid overriding intentional styling
|
|
66
|
+
*
|
|
67
|
+
* FLEX SHRINK BEHAVIOR RULES:
|
|
68
|
+
* ===========================
|
|
69
|
+
*
|
|
70
|
+
* For FLEX CONTAINERS:
|
|
71
|
+
* - If overflow is NOT handled AND no wrapping → flexShrink: 0 (prevent shrinking)
|
|
72
|
+
* - If overflow is handled OR wrapping enabled → flexShrink: undefined (allow default)
|
|
73
|
+
*
|
|
74
|
+
* For NON-FLEX CONTAINERS (flex items):
|
|
75
|
+
* - Always → flexShrink: 0 (prevent unwanted shrinking)
|
|
76
|
+
*
|
|
77
|
+
* NESTED SCENARIOS:
|
|
78
|
+
* ================
|
|
79
|
+
* An element can be both a flex container AND a flex item simultaneously.
|
|
80
|
+
* This function handles this correctly by checking if the element itself is a container,
|
|
81
|
+
* not whether it's inside a flex context.
|
|
82
|
+
*
|
|
83
|
+
* EXPLICIT VALUE PRESERVATION:
|
|
84
|
+
* ===========================
|
|
85
|
+
* - If user sets `flexShrink` explicitly → never override
|
|
86
|
+
* - If user sets `flex` shorthand → extract and use the shrink value from it
|
|
87
|
+
* - Otherwise → apply smart defaults based on context
|
|
88
|
+
* @param style The input CSSProperties object to process
|
|
89
|
+
* @returns Processed CSSProperties with resolved defaults
|
|
90
|
+
* @example
|
|
91
|
+
* // Fix scrollable flex item
|
|
92
|
+
* resolveDefaultStyle({
|
|
93
|
+
* overflow: 'auto',
|
|
94
|
+
* height: '200px'
|
|
95
|
+
* })
|
|
96
|
+
* // → { overflow: 'auto', height: '200px', flexShrink: 0, minHeight: 0, minWidth: 0 }
|
|
97
|
+
* @example
|
|
98
|
+
* // Flex container with wrapping (allows shrinking)
|
|
99
|
+
* resolveDefaultStyle({
|
|
100
|
+
* display: 'flex',
|
|
101
|
+
* flexWrap: 'wrap'
|
|
102
|
+
* })
|
|
103
|
+
* // → { display: 'flex', flexWrap: 'wrap', minHeight: 0, minWidth: 0 }
|
|
104
|
+
*/
|
|
105
|
+
static resolveDefaultStyle: (style: CSSInterpolation) => {};
|
|
106
|
+
}
|
|
107
|
+
export {};
|
|
108
|
+
//# sourceMappingURL=theme.util.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.util.d.ts","sourceRoot":"","sources":["../../src/util/theme.util.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACzE,OAAO,KAAK,EAAE,KAAK,EAAe,MAAM,yBAAyB,CAAA;AAiGjE;;;;;;GAMG;AACH,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;CACvB;AACD,qBAAa,SAAS;IACpB,OAAO,eAAiB;IAExB,OAAO,CAAC,MAAM,CAAC,UAAU,CAAmC;IAE5D;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAc,kBAAkB,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,cAAc,GAAG,IAAI,CA2BnF;IAED,OAAc,aAAa,0BAM1B;IAED;;;;;;;;OAQG;IACH,OAAc,mBAAmB;;cAoHhC;IAED,OAAc,eAAe,aAE5B;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAqDG;IACH,OAAc,mBAAmB,kCAmEhC;CACF"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
var _ThemeUtil,_excluded=["flex"];function _objectWithoutProperties(a,b){if(null==a)return{};var c,d,e=_objectWithoutPropertiesLoose(a,b);if(Object.getOwnPropertySymbols){var f=Object.getOwnPropertySymbols(a);for(d=0;d<f.length;d++)c=f[d],-1===b.indexOf(c)&&{}.propertyIsEnumerable.call(a,c)&&(e[c]=a[c])}return e}function _objectWithoutPropertiesLoose(a,b){if(null==a)return{};var c={};for(var d in a)if({}.hasOwnProperty.call(a,d)){if(-1!==b.indexOf(d))continue;c[d]=a[d]}return c}function ownKeys(a,b){var c=Object.keys(a);if(Object.getOwnPropertySymbols){var d=Object.getOwnPropertySymbols(a);b&&(d=d.filter(function(b){return Object.getOwnPropertyDescriptor(a,b).enumerable})),c.push.apply(c,d)}return c}function _objectSpread(a){for(var b,c=1;c<arguments.length;c++)b=null==arguments[c]?{}:arguments[c],c%2?ownKeys(Object(b),!0).forEach(function(c){_defineProperty(a,c,b[c])}):Object.getOwnPropertyDescriptors?Object.defineProperties(a,Object.getOwnPropertyDescriptors(b)):ownKeys(Object(b)).forEach(function(c){Object.defineProperty(a,c,Object.getOwnPropertyDescriptor(b,c))});return a}function _typeof(a){"@babel/helpers - typeof";return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},_typeof(a)}function _defineProperty(a,b,c){return(b=_toPropertyKey(b))in a?Object.defineProperty(a,b,{value:c,enumerable:!0,configurable:!0,writable:!0}):a[b]=c,a}function _toPropertyKey(a){var b=_toPrimitive(a,"string");return"symbol"==_typeof(b)?b:b+""}function _toPrimitive(a,b){if("object"!=_typeof(a)||!a)return a;var c=a[Symbol.toPrimitive];if(void 0!==c){var d=c.call(a,b||"default");if("object"!=_typeof(d))return d;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===b?String:Number)(a)}import{ObjHelper}from"../helper/obj.helper.js";import{getValueByPath}from"../helper/common.helper.js";/**
|
|
2
|
+
* Cache manager for theme resolution operations.
|
|
3
|
+
*/class ThemeResolverCache{constructor(){_defineProperty(this,"CACHE_SIZE_LIMIT",500),_defineProperty(this,"CACHE_EVICTION_BATCH_SIZE",50),_defineProperty(this,"_resolutionCache",new Map),_defineProperty(this,"_pathLookupCache",new Map),_defineProperty(this,"_themeRegex",/theme\.([a-zA-Z0-9_.-]+)/g)}static getInstance(){return ThemeResolverCache._instance||(ThemeResolverCache._instance=new ThemeResolverCache),ThemeResolverCache._instance}/**
|
|
4
|
+
* Generate a stable cache key from object and theme, including the theme mode.
|
|
5
|
+
*/_generateCacheKey(a,b){// Including theme.mode is critical for cache correctness.
|
|
6
|
+
return"".concat(ObjHelper.stringify(a),"_").concat(b.mode,"_").concat(ObjHelper.stringify(b.system))}getResolution(a,b){var c=this._generateCacheKey(a,b),d=this._resolutionCache.get(c);return d&&(this._resolutionCache["delete"](c),this._resolutionCache.set(c,d)),d||null}setResolution(a,b,c){var d=this._generateCacheKey(a,b);this._resolutionCache.set(d,c),this._resolutionCache.size>this.CACHE_SIZE_LIMIT&&this._evict(this._resolutionCache)}getPathLookup(a,b){var c="".concat(ObjHelper.stringify(a),"_").concat(b),d=this._pathLookupCache.get(c);return d&&(this._pathLookupCache["delete"](c),this._pathLookupCache.set(c,d)),d||null}setPathLookup(a,b,c){var d="".concat(ObjHelper.stringify(a),"_").concat(b);this._pathLookupCache.set(d,c),this._pathLookupCache.size>this.CACHE_SIZE_LIMIT&&this._evict(this._pathLookupCache)}_evict(a){for(var b,c=a.keys(),d=0;d<this.CACHE_EVICTION_BATCH_SIZE&&(b=c.next().value,b);d++)a["delete"](b)}getThemeRegex(){return this._themeRegex.lastIndex=0,this._themeRegex}shouldCache(){return"undefined"==typeof window}clear(){this._resolutionCache.clear(),this._pathLookupCache.clear()}}/**
|
|
7
|
+
* Parsed flex shorthand components for CSS flex property
|
|
8
|
+
* @interface FlexComponents
|
|
9
|
+
* @property grow - The flex-grow value (how much the item should grow)
|
|
10
|
+
* @property shrink - The flex-shrink value (how much the item should shrink)
|
|
11
|
+
* @property basis - The flex-basis value (initial main size before free space is distributed)
|
|
12
|
+
*/_defineProperty(ThemeResolverCache,"_instance",null);export class ThemeUtil{constructor(){}/**
|
|
13
|
+
* Parses a CSS flex shorthand property into its individual components.
|
|
14
|
+
*
|
|
15
|
+
* The CSS flex property is a shorthand for flex-grow, flex-shrink, and flex-basis.
|
|
16
|
+
* This parser handles the most common flex shorthand patterns to extract the shrink value
|
|
17
|
+
* when it's explicitly set by the user.
|
|
18
|
+
*
|
|
19
|
+
* Supported patterns:
|
|
20
|
+
* - Keywords: 'none' | 'auto' | 'initial'
|
|
21
|
+
* - Single number: '1' → {grow: 1, shrink: 1, basis: '0%'}
|
|
22
|
+
* - Full shorthand: '1 0 auto' → {grow: 1, shrink: 0, basis: 'auto'}
|
|
23
|
+
* @param flex The CSS flex property value to parse
|
|
24
|
+
* @returns FlexComponents object with parsed values, or null if unparseable
|
|
25
|
+
* @example
|
|
26
|
+
* parseFlexShorthand('none') // → {grow: 0, shrink: 0, basis: 'auto'}
|
|
27
|
+
* parseFlexShorthand('1') // → {grow: 1, shrink: 1, basis: '0%'}
|
|
28
|
+
* parseFlexShorthand('1 0 auto') // → {grow: 1, shrink: 0, basis: 'auto'}
|
|
29
|
+
*/static parseFlexShorthand(a){// Early returns for invalid inputs
|
|
30
|
+
if(null===a||a===void 0)return null;// Handle numeric flex values (e.g., flex: 1)
|
|
31
|
+
if("number"==typeof a)return{grow:a,shrink:1,basis:"0%"};if("string"!=typeof a)return null;var b=a.trim().toLowerCase();if(!b)return null;// Handle CSS keyword values
|
|
32
|
+
return"none"===b?{grow:0,shrink:0,basis:"auto"}:"auto"===b?{grow:1,shrink:1,basis:"auto"}:"initial"===b?{grow:0,shrink:1,basis:"auto"}:null}}/**
|
|
33
|
+
* Resolves theme variable references in an object's values iteratively.
|
|
34
|
+
* This function uses a manual work stack to traverse the object, which prevents
|
|
35
|
+
* "Maximum call stack size exceeded" errors for deeply nested objects.
|
|
36
|
+
* It performs a "smart merge" by using a copy-on-write strategy, creating new
|
|
37
|
+
* objects/arrays only when a value inside them has changed. This preserves
|
|
38
|
+
* object references for unchanged parts of the tree, which is critical for
|
|
39
|
+
* React's reconciliation and memoization.
|
|
40
|
+
*//**
|
|
41
|
+
* Resolves default CSS styles to fix common flexbox layout issues.
|
|
42
|
+
*
|
|
43
|
+
* PRIMARY PURPOSE: Fix the flexbox scrolling problem
|
|
44
|
+
* ================================================
|
|
45
|
+
*
|
|
46
|
+
* THE PROBLEM:
|
|
47
|
+
* By default, flex items have `min-width: auto` and `min-height: auto`, which means they
|
|
48
|
+
* cannot shrink below their content size. This prevents scrollable containers from working
|
|
49
|
+
* properly when they are flex items.
|
|
50
|
+
*
|
|
51
|
+
* THE SOLUTION:
|
|
52
|
+
* 1. Set `minHeight: 0` and `minWidth: 0` to allow flex items to shrink
|
|
53
|
+
* 2. Control `flexShrink` behavior based on context to prevent unwanted shrinking
|
|
54
|
+
* 3. Respect user's explicit values to avoid overriding intentional styling
|
|
55
|
+
*
|
|
56
|
+
* FLEX SHRINK BEHAVIOR RULES:
|
|
57
|
+
* ===========================
|
|
58
|
+
*
|
|
59
|
+
* For FLEX CONTAINERS:
|
|
60
|
+
* - If overflow is NOT handled AND no wrapping → flexShrink: 0 (prevent shrinking)
|
|
61
|
+
* - If overflow is handled OR wrapping enabled → flexShrink: undefined (allow default)
|
|
62
|
+
*
|
|
63
|
+
* For NON-FLEX CONTAINERS (flex items):
|
|
64
|
+
* - Always → flexShrink: 0 (prevent unwanted shrinking)
|
|
65
|
+
*
|
|
66
|
+
* NESTED SCENARIOS:
|
|
67
|
+
* ================
|
|
68
|
+
* An element can be both a flex container AND a flex item simultaneously.
|
|
69
|
+
* This function handles this correctly by checking if the element itself is a container,
|
|
70
|
+
* not whether it's inside a flex context.
|
|
71
|
+
*
|
|
72
|
+
* EXPLICIT VALUE PRESERVATION:
|
|
73
|
+
* ===========================
|
|
74
|
+
* - If user sets `flexShrink` explicitly → never override
|
|
75
|
+
* - If user sets `flex` shorthand → extract and use the shrink value from it
|
|
76
|
+
* - Otherwise → apply smart defaults based on context
|
|
77
|
+
* @param style The input CSSProperties object to process
|
|
78
|
+
* @returns Processed CSSProperties with resolved defaults
|
|
79
|
+
* @example
|
|
80
|
+
* // Fix scrollable flex item
|
|
81
|
+
* resolveDefaultStyle({
|
|
82
|
+
* overflow: 'auto',
|
|
83
|
+
* height: '200px'
|
|
84
|
+
* })
|
|
85
|
+
* // → { overflow: 'auto', height: '200px', flexShrink: 0, minHeight: 0, minWidth: 0 }
|
|
86
|
+
* @example
|
|
87
|
+
* // Flex container with wrapping (allows shrinking)
|
|
88
|
+
* resolveDefaultStyle({
|
|
89
|
+
* display: 'flex',
|
|
90
|
+
* flexWrap: 'wrap'
|
|
91
|
+
* })
|
|
92
|
+
* // → { display: 'flex', flexWrap: 'wrap', minHeight: 0, minWidth: 0 }
|
|
93
|
+
*/_ThemeUtil=ThemeUtil,_defineProperty(ThemeUtil,"themeCache",ThemeResolverCache.getInstance()),_defineProperty(ThemeUtil,"isPlainObject",function(a){if("object"!==_typeof(a)||null===a)return!1;var b=Object.getPrototypeOf(a);return null===b||b===Object.prototype}),_defineProperty(ThemeUtil,"resolveObjWithTheme",function(){var a,b=0<arguments.length&&void 0!==arguments[0]?arguments[0]:{},c=1<arguments.length?arguments[1]:void 0,d=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{},e=d.processFunctions;if(!c||!c.system||"object"!==_typeof(c.system)||0===Object.keys(c.system).length||0===Object.keys(b).length)return b;var f=c.system;if(_ThemeUtil.themeCache.shouldCache()){var g=_ThemeUtil.themeCache.getResolution(b,c);if(null!==g)return g}// Used for cycle detection within the current traversal path.
|
|
94
|
+
for(var h=[{value:b,isProcessed:!1}],j=new Map,k=new Set,l=function processThemeString(a){var b=_ThemeUtil.themeCache.getThemeRegex(),c=!1,d=a.replace(b,function(a,b){var d=_ThemeUtil.themeCache.getPathLookup(f,b);return null===d&&(d=getValueByPath(f,b),_ThemeUtil.themeCache.setPathLookup(f,b,d)),void 0!==d&&null!==d?(c=!0,"object"===_typeof(d)&&!Array.isArray(d)&&"default"in d?d["default"]:d):a});return c?d:a};0<h.length;){var m=h[h.length-1],n=m.value;if(!_ThemeUtil.isPlainObject(n)&&!Array.isArray(n)){h.pop();continue}if(j.has(n)){h.pop();continue}if(!m.isProcessed){m.isProcessed=!0,k.add(n);for(var o,p=Array.isArray(n)?n:Object.values(n),q=p.length-1;0<=q;q--)o=p[q],(_ThemeUtil.isPlainObject(o)||Array.isArray(o))&&!k.has(o)&&h.push({value:o,isProcessed:!1})}else{h.pop(),k["delete"](n);// Unwind the path
|
|
95
|
+
var r=n;if(Array.isArray(n)){for(var s=null,t=0;t<n.length;t++){var u,v=n[t],w=null!==(u=j.get(v))&&void 0!==u?u:v;w!==v&&(null===s&&(s=[...n]),s[t]=w)}null!==s&&(r=s)}else{var x=null;for(var y in n)if(Object.prototype.hasOwnProperty.call(n,y)){var z,A=n[y],B=null!==(z=j.get(A))&&void 0!==z?z:A;if("function"==typeof B&&void 0!==e&&e){var C=B(c);B="string"==typeof C&&C.includes("theme.")?l(C):C}else"string"==typeof B&&B.includes("theme.")&&(B=l(B));B!==A&&(null===x&&(x=_objectSpread({},n)),x[y]=B)}null!==x&&(r=x)}j.set(n,r)}}var D=null!==(a=j.get(b))&&void 0!==a?a:b;return _ThemeUtil.themeCache.shouldCache()&&_ThemeUtil.themeCache.setResolution(b,c,D),D}),_defineProperty(ThemeUtil,"clearThemeCache",function(){_ThemeUtil.themeCache.clear()}),_defineProperty(ThemeUtil,"resolveDefaultStyle",function(a){var b;if(null===a||a===void 0||"string"==typeof a||"number"==typeof a||"boolean"==typeof a)return{};// === STEP 1: EXTRACT FLEX PROPERTY ===
|
|
96
|
+
// Extract flex shorthand to handle it separately from individual flex properties
|
|
97
|
+
var c=a,d=c.flex,e=_objectWithoutProperties(c,_excluded),f="flex"===e.display||"inline-flex"===e.display,g=!!(e.overflow||e.overflowY||e.overflowX),h=(null===(b=e.flexFlow)||void 0===b?void 0:b.includes("wrap"))||"wrap"===e.flexWrap||"wrap-reverse"===e.flexWrap,i="flexShrink"in a&&a.flexShrink!==void 0,j=d?_ThemeUtil.parseFlexShorthand(d):null,k=void 0;// === STEP 2: ANALYZE LAYOUT CONTEXT ===
|
|
98
|
+
// Determine what kind of element we're dealing with
|
|
99
|
+
// Check if overflow is set (any overflow value indicates potential scrolling)
|
|
100
|
+
// Check if flex wrapping is enabled (allows items to wrap to new lines)
|
|
101
|
+
// === STEP 3: CHECK FOR EXPLICIT USER VALUES ===
|
|
102
|
+
// Respect user's explicit flexShrink setting
|
|
103
|
+
// Extract shrink value from flex shorthand if provided
|
|
104
|
+
// === STEP 4: DETERMINE FLEX SHRINK BEHAVIOR ===
|
|
105
|
+
// Only set flexShrink if user hasn't explicitly provided it
|
|
106
|
+
if(!i)// If flex shorthand contains a shrink value, use that
|
|
107
|
+
if(j)k=j.shrink;else// Apply context-based defaults
|
|
108
|
+
if(!f)// NON-FLEX CONTAINER LOGIC:
|
|
109
|
+
// Default flex-shrink to 0 to prevent unwanted shrinking of flex items
|
|
110
|
+
k=0;else// FLEX CONTAINER LOGIC:
|
|
111
|
+
// Only prevent shrinking when container is constrained (no overflow handling, no wrapping)
|
|
112
|
+
if(!g){var l="column"===e.flexDirection||"column-reverse"===e.flexDirection,m="row"===e.flexDirection||"row-reverse"===e.flexDirection||!e.flexDirection;l&&!h?k=0:m&&!h&&(k=0)}// === STEP 5: RETURN RESOLVED STYLES ===
|
|
113
|
+
// Combine all processed styles with essential defaults
|
|
114
|
+
return _objectSpread({flex:d,// Preserve original flex shorthand
|
|
115
|
+
flexShrink:k,// Apply computed or explicit flexShrink
|
|
116
|
+
minHeight:0,// Fix flex item scrolling issues
|
|
117
|
+
minWidth:0},e)});
|