@meonode/ui 0.2.9 → 0.2.11

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/dist/core.node.js CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";var _excluded=["ref","key","children","nodetheme","theme","props"],_excluded2=["style"],_excluded3=["style","css"],_excluded4=["style"],_excluded5=["children","key","nativeProps"];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 _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 _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,{Fragment,createElement,isValidElement}from"react";import{isNodeInstance,resolveDefaultStyle,resolveObjWithTheme}from"./helper/node.helper.js";import{isForwardRef,isFragment,isMemo,isReactClassComponent,isValidElementType}from"./helper/react-is.helper.js";import{createRoot}from"react-dom/client";import{getComponentType,getCSSProps,getDOMProps,getElementTypeName}from"./helper/common.helper.js";import StyledRenderer from"./components/styled-renderer.client.js";/**
1
+ "use strict";var _excluded=["ref","key","children","nodetheme","theme","props"],_excluded2=["style"],_excluded3=["style","css"],_excluded4=["style"],_excluded5=["children","key","nativeProps"];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 _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 _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,{Fragment,createElement,isValidElement}from"react";import{createStableHash,isNodeInstance,resolveDefaultStyle}from"./helper/node.helper.js";import{isForwardRef,isFragment,isMemo,isReactClassComponent,isValidElementType}from"./helper/react-is.helper.js";import{createRoot}from"react-dom/client";import{getComponentType,getCSSProps,getDOMProps,getElementTypeName,hasNoStyleTag,shallowEqual}from"./helper/common.helper.js";import StyledRenderer from"./components/styled-renderer.client.js";import{resolveObjWithTheme}from"./helper/theme.helper.js";/**
2
2
  * Represents a node in a React component tree with theme and styling capabilities.
3
3
  * This class wraps React elements and handles:
4
4
  * - Props processing and normalization
@@ -7,113 +7,200 @@
7
7
  * - Style processing with theme variables
8
8
  * @template E The type of React element or component this node represents
9
9
  */export class BaseNode{/**
10
- * Creates a new BaseNode instance that wraps a React element.
11
- * Processes raw props by:
12
- * - Extracting and resolving theme-aware styles
13
- * - Processing DOM-related props
14
- * - Normalizing children with theme inheritance
15
- * @param element The React element/component to wrap
16
- * @param rawProps Initial props including theme, styles, and children
17
- */constructor(a){var b=this,c=1<arguments.length&&arguments[1]!==void 0?arguments[1]:{};_defineProperty(this,"rawProps",{}),_defineProperty(this,"isBaseNode",!0),_defineProperty(this,"_portalDOMElement",null),_defineProperty(this,"_portalReactRoot",null),_defineProperty(this,"_normalizeChild",function(a){var c,d;if(!a)return a;var e=(null===(c=b.rawProps)||void 0===c?void 0:c.nodetheme)||(null===(d=b.rawProps)||void 0===d?void 0:d.theme)||b.props.nodetheme||b.props.theme;// For BaseNode instances, apply current theme if child has no theme
10
+ * Constructs a new BaseNode instance.
11
+ *
12
+ * This constructor initializes a node with a given React element or component type
13
+ * and the raw props passed to it. The props are not processed until they are
14
+ * accessed via the `props` getter, allowing for lazy evaluation.
15
+ * @param element The React element or component type this node will represent.
16
+ * @param rawProps The initial, unprocessed props for the element.
17
+ */constructor(a){var b=this,c=1<arguments.length&&arguments[1]!==void 0?arguments[1]:{};/** The underlying React element or component type that this node represents *//** Original props passed during construction, preserved for cloning/recreation *//** Flag to identify BaseNode instances *//** DOM element used for portal rendering *//** React root instance for portal rendering *//**
18
+ * Generates a stable key for a node, especially for elements within an array.
19
+ *
20
+ * If an `existingKey` is provided, it is returned. Otherwise, a key is generated
21
+ * based on the element's type name and its index within a list of siblings.
22
+ * This helps prevent re-rendering issues in React when dealing with dynamic lists.
23
+ * @param options The options for key generation.
24
+ * @param options.nodeIndex The index of the node in an array of children.
25
+ * @param options.element The element for which to generate a key.
26
+ * @param options.existingKey An existing key, if one was already provided.
27
+ * @param options.children The children of the node, used to add complexity to the key.
28
+ * @returns A React key, or `undefined` if no key could be generated.
29
+ * @private
30
+ *//**
31
+ * Normalizes a processed child node into a final, renderable `ReactNode`.
32
+ *
33
+ * This method is called during the `render` phase. It takes a child that has already
34
+ * been processed by `_processChildren` and prepares it for `React.createElement`.
35
+ *
36
+ * - For `BaseNode` instances, it calls their `render()` method, ensuring the theme is consistent.
37
+ * - It validates that other children are valid React element types.
38
+ * - Primitives and other valid nodes are returned as-is.
39
+ * @param child The processed child node to normalize.
40
+ * @returns A renderable `ReactNode`.
41
+ * @throws {Error} If the child is not a valid React element type.
42
+ * @private
43
+ */_defineProperty(this,"rawProps",{}),_defineProperty(this,"isBaseNode",!0),_defineProperty(this,"_portalDOMElement",null),_defineProperty(this,"_portalReactRoot",null),_defineProperty(this,"_generateKey",function(a){var b=a.nodeIndex,c=a.element,d=a.existingKey,e=a.children;if(d)return d;var f,g=getElementTypeName(c);return f=Array.isArray(e)&&0<e.length?void 0===b?"".concat(g,"-").concat(e.length):"".concat(g,"-").concat(b,"-").concat(e.length):void 0===b?g:"".concat(g,"-").concat(b),f}),_defineProperty(this,"_normalizeChild",function(a){var c,d;if(!a)return a;var e=(null===(c=b.rawProps)||void 0===c?void 0:c.nodetheme)||(null===(d=b.rawProps)||void 0===d?void 0:d.theme)||b.props.nodetheme||b.props.theme;// For BaseNode instances, apply current theme if child has no theme
18
44
  if(a instanceof BaseNode){var f;return null!==(f=a.rawProps)&&void 0!==f&&f.nodetheme||void 0===e?a.render():new BaseNode(a.element,_objectSpread(_objectSpread({},a.rawProps),{},{nodetheme:e})).render()}// Validate element type before returning
19
45
  if(!isValidElementType(a)){var g=getComponentType(a);throw new Error("Invalid element type: ".concat(g," provided!"))}// Return valid React elements as-is
20
- return a}),this.element=a,this.rawProps=c;// Destructure raw props into relevant parts
21
- var d=c.ref,e=c.key,f=c.children,g=c.nodetheme,h=c.theme,i=c.props,j=void 0===i?{}:i,k=_objectWithoutProperties(c,_excluded),l=h||g,m=j,n=m.style,o=_objectWithoutProperties(m,_excluded2),p=resolveObjWithTheme(k,l),q=resolveObjWithTheme(n,l),r=p.style,s=p.css,t=_objectWithoutProperties(p,_excluded3),u=getCSSProps(t),v=getDOMProps(t),w=resolveDefaultStyle(_objectSpread(_objectSpread({},u),r)),x=this._processChildren(f,l);// Process children while maintaining theme inheritance
46
+ return a}),this.element=a,this.rawProps=c}/**
47
+ * Lazily processes and retrieves the final, normalized props for the node.
48
+ *
49
+ * The first time this getter is accessed, it triggers `_processProps` to resolve
50
+ * themes, styles, and children. Subsequent accesses return the cached result
51
+ * until the node is cloned or recreated.
52
+ * @returns The fully processed and normalized `FinalNodeProps`.
53
+ */get props(){return this._props||(this._props=this._processProps()),this._props}/**
54
+ * Performs the core logic of processing raw props into their final, normalized form.
55
+ *
56
+ * This method is called by the `props` getter on its first access. It handles:
57
+ * 1. **Theme Resolution**: Selects the active theme from `theme` or `nodetheme` props.
58
+ * 2. **Prop Resolution**: Resolves theme-aware values (functions) in `rawProps` and `nativeProps.style`.
59
+ * 3. **Style Extraction**: Separates style-related props (`css`, `style`) from other DOM/component props.
60
+ * 4. **Default Style Merging**: Combines default styles with resolved style props.
61
+ * 5. **Child Processing**: Normalizes the `children` prop, propagating the theme.
62
+ * @returns The processed `FinalNodeProps` object.
63
+ * @private
64
+ */_processProps(){// Destructure raw props into relevant parts
65
+ var a=this.rawProps,b=a.ref,c=a.key,d=a.children,e=a.nodetheme,f=a.theme,g=a.props,h=void 0===g?{}:g,i=_objectWithoutProperties(a,_excluded),j=f||e,k=h,l=k.style,m=_objectWithoutProperties(k,_excluded2),n=resolveObjWithTheme(i,j),o=resolveObjWithTheme(l,j),p=n.style,q=n.css,r=_objectWithoutProperties(n,_excluded3),s=getCSSProps(r),t=getDOMProps(r),u=resolveDefaultStyle(_objectSpread(_objectSpread({},s),p)),v=this._processChildren(d,j);// Process children while maintaining theme inheritance
22
66
  // Combine processed props into final normalized form
23
- this.props=_objectSpread(_objectSpread({ref:d,key:e,nodetheme:l,theme:h,css:_objectSpread(_objectSpread({},w),s),style:q},v),{},{nativeProps:o,children:x})}_processChildren(a,b){var c=this;return a?Array.isArray(a)?a.map(function(a,d){return c._processRawNode(a,b,d)}):this._processRawNode(a,b):void 0}/**
24
- * Renders a processed NodeElement into a ReactNode, applying theme and key if needed.
67
+ return _objectSpread(_objectSpread({ref:b,key:c,nodetheme:j,theme:f,css:_objectSpread(_objectSpread({},u),q),style:o},t),{},{nativeProps:m,children:v})}/**
68
+ * Processes raw children, wrapping them in `BaseNode` instances where necessary
69
+ * and propagating the theme.
25
70
  *
26
- * Handles the following cases:
27
- * 1. If the element is a BaseNode instance, it re-wraps it to apply the key and theme if needed.
28
- * 2. If the element is a React class component type, it wraps it in a BaseNode.
29
- * 3. If the element is a NodeInstance object, it calls its render method.
30
- * 4. If the element is a React.Component instance, it calls its render method.
31
- * 5. If the element is a functional component, it creates a React element with the provided key.
32
- * 6. For all other valid ReactNode types, it returns the element as-is.
33
- * @param processedElement The processed node element to render.
34
- * @param passedTheme The theme to apply, if any.
35
- * @param passedKey The key to assign, if any.
36
- * @returns The rendered ReactNode.
71
+ * This method recursively processes each child to ensure consistent theme handling
72
+ * and to convert valid elements into `BaseNode` instances. It uses caching to
73
+ * optimize performance, with different strategies for server-side (string-based key)
74
+ * and client-side (WeakMap-based key) environments.
75
+ * @param children The raw child or array of children to process.
76
+ * @param theme The theme to propagate to the children.
77
+ * @returns The processed children, ready to be normalized for rendering.
78
+ * @private
79
+ */_processChildren(a,b){var c=this;if(a){// On server, use a Map with a stable hash for more effective and performant caching.
80
+ if("undefined"==typeof window){1e3<BaseNode._childProcessingCache.size&&BaseNode._childProcessingCache.clear();var d=createStableHash(a,b);if(BaseNode._childProcessingCache.has(d))return BaseNode._childProcessingCache.get(d);var e=Array.isArray(a)?a.map(function(a,d){return c._processRawNode(a,b,d)}):this._processRawNode(a,b);return BaseNode._childProcessingCache.set(d,e),e}// Client-side caching was ineffective and has been removed.
81
+ // Processing children on the client is fast enough and avoids complex, buggy cache logic.
82
+ return Array.isArray(a)?a.map(function(a,d){return c._processRawNode(a,b,d)}):this._processRawNode(a,b)}}/**
83
+ * Renders a processed `NodeElement` into a `ReactNode`, applying a theme and key if necessary.
84
+ *
85
+ * This static method centralizes the logic for converting various types of processed elements
86
+ * into renderable React nodes. It handles:
87
+ * - `BaseNode` instances: Re-wraps them to apply a new key or theme.
88
+ * - React class components: Wraps them in a new `BaseNode`.
89
+ * - `NodeInstance` objects: Invokes their `render()` method.
90
+ * - React component instances: Invokes their `render()` method.
91
+ * - Functional components: Creates a React element from them.
92
+ * - Other valid `ReactNode` types (strings, numbers, etc.): Returns them as-is.
93
+ * @param processedElement The node element to render.
94
+ * @param passedTheme The theme to propagate.
95
+ * @param passedKey The React key to assign.
96
+ * @returns A renderable `ReactNode`.
97
+ * @private
98
+ * @static
37
99
  */static _renderProcessedNode(a,b,c){var d={};// 1. BaseNode instance: re-wrap to apply key/theme if needed
38
- if(void 0!==c&&(d.key=c),a instanceof BaseNode){var e,f,g=(null===(e=a.rawProps)||void 0===e?void 0:e.theme)||(null===(f=a.rawProps)||void 0===f?void 0:f.nodetheme)||b;return new BaseNode(a.element,_objectSpread(_objectSpread(_objectSpread({},a.rawProps),d),{},{nodetheme:g})).render()}// 2. React class component type: wrap in BaseNode
100
+ if(void 0!==c&&(d.key=c),a instanceof BaseNode){var e,f,g,h,i,j=(null===(e=a.rawProps)||void 0===e?void 0:e.theme)||(null===(f=a.rawProps)||void 0===f?void 0:f.nodetheme)||b;// Avoid creating new BaseNode if props are identical
101
+ return shallowEqual(d,{key:null===(g=a.rawProps)||void 0===g?void 0:g.key})&&j===((null===(h=a.rawProps)||void 0===h?void 0:h.nodetheme)||(null===(i=a.rawProps)||void 0===i?void 0:i.theme))?a.render():new BaseNode(a.element,_objectSpread(_objectSpread(_objectSpread({},a.rawProps),d),{},{nodetheme:j})).render()}// 2. React class component type: wrap in BaseNode
39
102
  return isReactClassComponent(a)?new BaseNode(a,d).render():isNodeInstance(a)?a.render():a instanceof React.Component?a.render():"function"==typeof a?createElement(a,{key:c}):a;// 3. NodeInstance object: call its render
40
103
  // 4. React.Component instance: call its render
41
104
  // 5. Functional component: create element with key
42
105
  // 6. Other valid ReactNode types
43
106
  }/**
44
- * Renders the result of a function child, supporting theme propagation.
107
+ * Renders the output of a function-as-a-child, ensuring theme propagation.
45
108
  *
46
- * Used for children that are functions (`() => Children`). If the returned value is a `BaseNode`
47
- * without an explicit theme, the parent theme is injected. Otherwise, the result is rendered as-is.
48
- * @template E - The type of ReactNode or NodeInstance.
49
- * @param props Renderer props.
50
- * @param props.render Function to invoke for rendering the child.
51
- * @param props.passedTheme Theme to provide to the child, if applicable.
52
- * @param props.passedKey Key to assign to the rendered node.
53
- * @param props.processRawNode Function to process raw nodes.
54
- * @returns The rendered ReactNode, with theme applied if necessary.
109
+ * This method is designed to handle "render prop" style children (`() => ReactNode`).
110
+ * It invokes the function, processes its result, and ensures the parent's theme is
111
+ * correctly passed down to any `BaseNode` instances returned by the function.
112
+ * @param props The properties for the function renderer.
113
+ * @param props.render The function to execute to get the child content.
114
+ * @param props.passedTheme The theme to propagate to the rendered child.
115
+ * @param props.passedKey The React key to assign to the rendered node.
116
+ * @param props.processRawNode A reference to the `_processRawNode` method for recursive processing.
117
+ * @returns The rendered `ReactNode`.
118
+ * @private
55
119
  */_functionRenderer(a){var b=a.render,c=a.passedTheme,d=a.passedKey,e=a.processRawNode,f=b();// Invoke the render function to get the child node.
56
120
  // Handle React.Component instance
57
121
  if(f instanceof React.Component){var g=f.render(),h=e(g,c);return BaseNode._renderProcessedNode(h,c,d)}// Handle BaseNode instance
58
122
  if(f instanceof BaseNode||isNodeInstance(f)){var i,j=f;return void 0===(null===(i=j.rawProps)||void 0===i?void 0:i.nodetheme)&&void 0!==c?new BaseNode(j.element,_objectSpread(_objectSpread({key:d},j.rawProps),{},{nodetheme:c})).render():j.render()}// Process other result types
59
123
  var k=e(f,c);return k?BaseNode._renderProcessedNode(k,c,d):f}/**
60
- * Processes a single raw child element, converting it into a ProcessedChild.
61
- * If the child is part of an array and lacks an explicit key, a stable indexed key
62
- * (`elementName_child_index`) is generated for new BaseNode instances.
63
- * @param rawNode The raw child element to process.
64
- * @param parentTheme The theme inherited from the parent node.
65
- * @param nodeIndex Optional index of the child if it's part of an array.
66
- * @returns The processed child.
124
+ * Processes a single raw node, recursively converting it into a `BaseNode` or other renderable type.
125
+ *
126
+ * This is a central method for normalizing children. It handles various types of input:
127
+ * - **`BaseNode` instances**: Re-creates them to ensure the correct theme and key are applied.
128
+ * - **Primitives**: Returns strings, numbers, booleans, null, and undefined as-is.
129
+ * - **Functions (Render Props)**: Wraps them in a `BaseNode` that uses `_functionRenderer` to delay execution.
130
+ * - **Valid React Elements**: Converts them into `BaseNode` instances, extracting props and propagating the theme.
131
+ * - **React Component Types**: Wraps them in a `BaseNode` with the parent theme.
132
+ * - **React Component Instances**: Renders them and processes the output recursively.
133
+ *
134
+ * It also generates a stable key for elements within an array if one is not provided.
135
+ * @param rawNode The raw child node to process.
136
+ * @param parentTheme The theme inherited from the parent.
137
+ * @param nodeIndex The index of the child if it is in an array, used for key generation.
138
+ * @returns A processed `NodeElement` (typically a `BaseNode` instance or a primitive).
139
+ * @private
67
140
  */_processRawNode(a,b,c// Index for generating stable keys for array children
68
- ){var d=getComponentType(a),e=function generateKey(a){var b=a.element,d=a.existingKey,e=a.children;if(d)return d;var f=getElementTypeName(b);return Array.isArray(e)&&0<e.length?void 0===c?"".concat(f,"-").concat(e.length):"".concat(f,"-").concat(c,"-").concat(e.length):void 0===c?f:"".concat(f,"-").concat(c)};// Determine the type of the raw node
69
- // Helper to generate an indexed key if no explicit key is present and an index is available.
141
+ ){var d=getComponentType(a);// Determine the type of the raw node
70
142
  // Case 1: Child is already a BaseNode instance
71
- if(a instanceof BaseNode){var f=a,g=f.rawProps||{},h=g.theme||g.nodetheme||b,i=e({element:f.element,existingKey:g.key,children:g.children});// Get initial raw props of the child
143
+ if(a instanceof BaseNode){var e=a,f=e.rawProps||{},g=f.theme||f.nodetheme||b;// Get initial raw props of the child
72
144
  // Prefer child's own theme
73
- // Generate key if needed
74
- return new BaseNode(f.element,_objectSpread(_objectSpread({},g),{},{nodetheme:h,// Use the determined theme for the new node
75
- key:i}));// Create a new BaseNode with merged props and theme
145
+ // Check if we can reuse the existing node
146
+ if(f.nodetheme===g&&f.key!==void 0)return e;var h=this._generateKey({nodeIndex:c,element:e.element,existingKey:f.key,children:f.children});// Generate key if needed
147
+ return new BaseNode(e.element,_objectSpread(_objectSpread({},f),{},{nodetheme:g,// Use the determined theme for the new node
148
+ key:h}));// Create a new BaseNode with merged props and theme
76
149
  }// Case 2: Child is a primitive (string, number, boolean, null, undefined)
77
150
  if("string"===d||"number"===d||"boolean"===d||null===a||void 0===a)return a;// Case 3: Child is a function that needs to be called during render (FunctionRenderer).
78
151
  if("function"===d&&!isReactClassComponent(a)&&!isMemo(a)&&!isForwardRef(a)){// The key is for the BaseNode that wraps the _functionRenderer component.
79
152
  // Functions themselves don't have a .key prop that we can access here.
80
- var j=e({element:this._functionRenderer});// Generate key for function renderer
81
- return new BaseNode(this._functionRenderer,{processRawNode:this._processRawNode.bind(this),render:a,passedTheme:b,key:j})}// Case 4: Child is a React Element (JSX element like <div> or <MyComponent>)
82
- if(isValidElement(a)){var k=a.props,l=k.style,m=_objectWithoutProperties(k,_excluded4),n=_objectSpread(_objectSpread({},m),l||{}),o=n.theme||n.nodetheme||b,p=e({element:a.type,existingKey:a.key,children:n.children});// Combine top-level props from the element with its flattened style object properties
83
- return new BaseNode(a.type,_objectSpread(_objectSpread({},n),{},{// Pass the combined props
84
- nodetheme:o,key:p}))}// Case 5: Child is an ElementType (string tag, class component, Memo/ForwardRef)
85
- if(isReactClassComponent(a)||"object"===d&&(isMemo(a)||isForwardRef(a))){var q,r=e({element:a,children:"object"===_typeof(a)&&"props"in a?null===(q=a.props)||void 0===q?void 0:q.children:void 0});// ElementTypes don't have an intrinsic key from the rawNode itself.
153
+ var i=this._generateKey({nodeIndex:c,element:this._functionRenderer});// Generate key for function renderer
154
+ return new BaseNode(this._functionRenderer,{processRawNode:this._processRawNode.bind(this),render:a,passedTheme:b,key:i})}// Case 4: Child is a React Element (JSX element like <div> or <MyComponent>)
155
+ if(isValidElement(a)){var j=a.props,k=j.style,l=_objectWithoutProperties(j,_excluded4),m=_objectSpread(_objectSpread({},l),k||{}),n=m.theme||m.nodetheme||b,o=this._generateKey({nodeIndex:c,element:a.type,existingKey:a.key,children:m.children});// Combine top-level props from the element with its flattened style object properties
156
+ return new BaseNode(a.type,_objectSpread(_objectSpread({},m),{},{// Pass the combined props
157
+ nodetheme:n,key:o}))}// Case 5: Child is an ElementType (string tag, class component, Memo/ForwardRef)
158
+ if(isReactClassComponent(a)||"object"===d&&(isMemo(a)||isForwardRef(a))){var p,q=this._generateKey({nodeIndex:c,element:a,children:"object"===_typeof(a)&&"props"in a?null===(p=a.props)||void 0===p?void 0:p.children:void 0});// ElementTypes don't have an intrinsic key from the rawNode itself.
86
159
  return new BaseNode(a,{nodetheme:b,// Apply parent theme
87
- key:r})}// Case 6: Handle instances of React.Component
88
- if(a instanceof React.Component){var s=a.render();// Recursively process the rendered element with a parent theme and index if available
89
- return this._processRawNode(s,b,c)}// Case 7: Fallback for other ReactNode types (e.g., Fragments, Portals if not caught by isValidElement)
160
+ key:q})}// Case 6: Handle instances of React.Component
161
+ if(a instanceof React.Component){var r=a.render();// Recursively process the rendered element with a parent theme and index if available
162
+ return this._processRawNode(r,b,c)}// Case 7: Fallback for other ReactNode types (e.g., Fragments, Portals if not caught by isValidElement)
90
163
  // These are returned as-is. If they are elements within an array, React expects them to have keys.
91
164
  // This logic primarily adds keys to BaseNode instances we create, other ReactNodes are returned as-is.
92
165
  return a}/**
93
- * Normalizes a child node into a renderable ReactNode.
94
- * Processes different types of child nodes to ensure they can be properly rendered
95
- * while maintaining theme inheritance.
166
+ * Renders the `BaseNode` into a `ReactElement`.
96
167
  *
97
- * Handles:
98
- * - BaseNode instances (applies theme if needed)
99
- * - React.Component instances (applies theme if needed)
100
- * - Other valid React element types (returned as-is)
101
- * - null/undefined values (returned as-is)
102
- * @param child The child node to normalize into a renderable form
103
- * @returns The normalized ReactNode that can be rendered by React
104
- * @throws Error if child is an invalid element type
105
- *//**
106
- * Converts this BaseNode instance into a renderable React node.
107
- * Recursively processes child nodes and uses `React.createElement` to construct the final React element.
108
- * @returns A ReactNode representing the rendered element.
168
+ * This method is the final step in the rendering pipeline. It constructs a React element
169
+ * by:
170
+ * 1. Validating that the node's `element` type is renderable.
171
+ * 2. Normalizing processed children into `ReactNode`s using `_normalizeChild`.
172
+ * 3. Caching normalized children to avoid re-processing on subsequent renders.
173
+ * 4. Assembling the final props, including `key`, `style`, and other attributes.
174
+ * 5. If the element has a `css` prop, it may be wrapped in a `StyledRenderer` to handle
175
+ * CSS-in-JS styling.
176
+ * 6. Finally, calling `React.createElement` with the element, props, and children.
177
+ * @returns The rendered `ReactElement`.
178
+ * @throws {Error} If the node's `element` is not a valid React element type.
109
179
  */render(){var a=this;if(!isValidElementType(this.element)){var b=getComponentType(this.element);throw new Error("Invalid element type: ".concat(b," provided!"))}// Extract children and key
110
- var c=this.props,d=c.children,e=c.key,f=c.nativeProps,g=_objectWithoutProperties(c,_excluded5),h=void 0;if(void 0!==d&&null!==d)if(!Array.isArray(d))h=this._normalizeChild(d);else if(0<d.length){// Normalize each child in the array
111
- var i=d.map(function(b){return a._normalizeChild(b)});// Check if all children are null/undefined (e.g., conditional rendering resulted in nothing)
112
- h=i.every(function(a){return null===a||void 0===a})?void 0:i}else// Empty array of children
113
- h=void 0;// Prepare props for React.createElement
114
- var j;// If the element has css props, render using the StyledRenderer component
115
- // This allows for styles to be handled by emotion
116
- return j=this.element===Fragment||isFragment(this.element)?{key:e}:_objectSpread(_objectSpread(_objectSpread({},g),{},{key:e},f),{},{suppressHydrationWarning:!0}),this.element&&j.css?createElement(StyledRenderer,_objectSpread({element:this.element},j),h):createElement(this.element,j,h)}_ensurePortalInfrastructure(){if("undefined"==typeof window)return!1;if(this._portalDOMElement&&this._portalReactRoot)return!0;if(this._portalDOMElement&&!this._portalDOMElement.isConnected&&(this._portalDOMElement=null,this._portalDOMElement=null),this._portalDOMElement||(this._portalDOMElement=document.createElement("div"),document.body.appendChild(this._portalDOMElement)),!this._portalReactRoot){if(!this._portalDOMElement)return!1;this._portalReactRoot=createRoot(this._portalDOMElement)}return!0}toPortal(){var a=this;if(!this._ensurePortalInfrastructure()||!this._portalReactRoot)return null;var b=this.render();return this._portalReactRoot.render(b),_objectSpread(_objectSpread({},this._portalReactRoot),{},{unmount:function unmount(){a._portalReactRoot&&(a._portalReactRoot.unmount(),a._portalReactRoot=null),a._portalDOMElement&&(a._portalDOMElement.parentNode&&a._portalDOMElement.parentNode.removeChild(a._portalDOMElement),a._portalDOMElement=null)}})}}/**
180
+ var c=this.props,d=c.children,e=c.key,f=c.nativeProps,g=_objectWithoutProperties(c,_excluded5),h=void 0;if(void 0!==d&&null!==d){if(!this._normalizedChildren||this._childrenHash!==createStableHash(d,this.props.nodetheme||this.props.theme))if(!Array.isArray(d))this._normalizedChildren=this._normalizeChild(d);else if(0<d.length){var i=d.map(function(b){return a._normalizeChild(b)});this._normalizedChildren=i.every(function(a){return null===a||void 0===a})?void 0:i}else this._normalizedChildren=void 0;h=this._normalizedChildren}// Prepare props for React.createElement
181
+ var j;// If the element has a `css` prop and has style tag, render using the `StyledRenderer` component
182
+ // This enables emotion-based style handling for the element
183
+ return j=this.element===Fragment||isFragment(this.element)?{key:e}:_objectSpread(_objectSpread(_objectSpread({},g),{},{key:e},f),{},{suppressHydrationWarning:!0}),this.element&&!hasNoStyleTag(this.element)&&j.css?createElement(StyledRenderer,_objectSpread({element:this.element},j),h):createElement(this.element,j,h)}/**
184
+ * Ensures the necessary DOM elements for portal rendering are created and attached.
185
+ *
186
+ * On the client-side, this method checks for or creates a `div` element appended
187
+ * to the `document.body` and initializes a React root on it. This setup is
188
+ * required for the `toPortal` method to function. It is idempotent and safe
189
+ * to call multiple times.
190
+ * @returns `true` if the portal infrastructure is ready, `false` if on the server.
191
+ * @private
192
+ */_ensurePortalInfrastructure(){if("undefined"==typeof window)return!1;if(this._portalDOMElement&&this._portalReactRoot)return!0;if(this._portalDOMElement&&!this._portalDOMElement.isConnected&&(this._portalDOMElement=null,this._portalDOMElement=null),this._portalDOMElement||(this._portalDOMElement=document.createElement("div"),document.body.appendChild(this._portalDOMElement)),!this._portalReactRoot){if(!this._portalDOMElement)return!1;this._portalReactRoot=createRoot(this._portalDOMElement)}return!0}/**
193
+ * Renders the node into a React Portal.
194
+ *
195
+ * This method mounts the node's rendered content into a separate DOM tree
196
+ * attached to the `document.body`. It's useful for rendering components like
197
+ * modals, tooltips, or notifications that need to appear above other UI elements.
198
+ *
199
+ * The returned object includes an `unmount` function to clean up the portal.
200
+ * @returns A `ReactDOMRoot` instance for managing the portal, or `null` if
201
+ * called in a server-side environment. The returned instance is enhanced
202
+ * with a custom `unmount` method that also cleans up the associated DOM element.
203
+ */toPortal(){var a=this;if(!this._ensurePortalInfrastructure()||!this._portalReactRoot)return null;var b=this.render();return this._portalReactRoot.render(b),_objectSpread(_objectSpread({},this._portalReactRoot),{},{unmount:function unmount(){a._portalReactRoot&&(a._portalReactRoot.unmount(),a._portalReactRoot=null),a._portalDOMElement&&(a._portalDOMElement.parentNode&&a._portalDOMElement.parentNode.removeChild(a._portalDOMElement),a._portalDOMElement=null)}})}}/**
117
204
  * Factory function to create a `BaseNode` instance.
118
205
  * @template AdditionalProps Additional props to merge with node props.
119
206
  * @template E The React element or component type.
@@ -121,7 +208,7 @@ return j=this.element===Fragment||isFragment(this.element)?{key:e}:_objectSpread
121
208
  * @param props The props for the node (optional).
122
209
  * @param additionalProps Additional props to merge into the node (optional).
123
210
  * @returns A new `BaseNode` instance as a `NodeInstance<E>`.
124
- */export function Node(a){var b=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{},c=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{},d=_objectSpread(_objectSpread({},b),c);return d.theme&&!d.nodetheme&&(d.nodetheme=d.theme),new BaseNode(a,d)}/**
211
+ */_defineProperty(BaseNode,"_childProcessingCache",new Map);export function Node(a){var b=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{},c=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{},d=_objectSpread(_objectSpread({},b),c);return d.theme&&!d.nodetheme&&(d.nodetheme=d.theme),new BaseNode(a,d)}/**
125
212
  * Creates a curried node factory for a given React element or component type.
126
213
  *
127
214
  * Returns a function that, when called with props, produces a `BaseNode` instance.
@@ -71,4 +71,12 @@ export declare function getCSSProps<T extends Record<string, any>>(props: T): Pa
71
71
  * @returns An object containing only valid DOM props.
72
72
  */
73
73
  export declare function getDOMProps<E extends ElementType, T extends ComponentProps<E>>(props: T): Partial<FinalNodeProps>;
74
+ /**
75
+ * Checks if a given tag is in the set of tags that should not receive style props.
76
+ * @param tag The tag name to check (e.g., 'script', 'style').
77
+ * @returns `true` if the tag is in the no-style set, otherwise `false`.
78
+ */
79
+ export declare function hasNoStyleTag(tag?: NodeElement): boolean;
80
+ // Shallow comparison utility
81
+ export declare function shallowEqual(obj1: any, obj2: any): boolean;
74
82
  //# sourceMappingURL=common.helper.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"common.helper.d.ts","sourceRoot":"","sources":["../../src/helper/common.helper.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAEpE,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AAEvE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,cAAc,iCAE1B,CAAA;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,gBAAgB,qCAmC5B,CAAA;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAsFxD;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,GAAG,CAAC,MAAM,CAA0B,CAAA;AAEjE;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,CAU3F;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,WAAW,EAAE,CAAC,SAAS,cAAc,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,cAAc,CAAC,CAUjH"}
1
+ {"version":3,"file":"common.helper.d.ts","sourceRoot":"","sources":["../../src/helper/common.helper.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAEpE,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AAGvE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,cAAc,iCAE1B,CAAA;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,gBAAgB,qCAmC5B,CAAA;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAsFxD;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,GAAG,CAAC,MAAM,CAA0B,CAAA;AAEjE;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,CAU3F;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,WAAW,EAAE,CAAC,SAAS,cAAc,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,cAAc,CAAC,CAUjH;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,CAAC,EAAE,WAAW,GAAG,OAAO,CAGxD;AAED,6BAA6B;AAC7B,wBAAgB,YAAY,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,GAAG,OAAO,CAgB1D"}
@@ -1,4 +1,4 @@
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)}import{isContextConsumer,isContextProvider,isElement,isForwardRef,isFragment,isLazy,isMemo,isPortal,isProfiler,isReactClassComponent,isStrictMode,isSuspense,isSuspenseList}from"./react-is.helper.js";import cssProperties from"../data/css-properties.js";/**
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)}import{isContextConsumer,isContextProvider,isElement,isForwardRef,isFragment,isLazy,isMemo,isPortal,isProfiler,isReactClassComponent,isStrictMode,isSuspense,isSuspenseList}from"./react-is.helper.js";import cssProperties from"../constants/css-properties.const.js";import{noStyleTagsSet}from"../constants/common.const.js";/**
2
2
  * Retrieves a deeply nested value from an object using a dot-separated string path.
3
3
  *
4
4
  * This function traverses an object based on the provided path, which is a
@@ -57,4 +57,9 @@ function _typeof(a){"@babel/helpers - typeof";return _typeof="function"==typeof
57
57
  * @typeParam T - The type of the component props.
58
58
  * @param props The component props to filter.
59
59
  * @returns An object containing only valid DOM props.
60
- */export function getDOMProps(a){var b={};for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&!CSSPropertySet.has(c)&&(b[c]=a[c]);return b}
60
+ */export function getDOMProps(a){var b={};for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&!CSSPropertySet.has(c)&&(b[c]=a[c]);return b}/**
61
+ * Checks if a given tag is in the set of tags that should not receive style props.
62
+ * @param tag The tag name to check (e.g., 'script', 'style').
63
+ * @returns `true` if the tag is in the no-style set, otherwise `false`.
64
+ */export function hasNoStyleTag(a){return!!(a&&"string"==typeof a)&&noStyleTagsSet.has(a.toLowerCase())}// Shallow comparison utility
65
+ export function shallowEqual(a,b){if(a===b)return!0;if(!a||!b)return!1;if("object"!==_typeof(a)||"object"!==_typeof(b))return a===b;var c=Object.keys(a),d=Object.keys(b);if(c.length!==d.length)return!1;for(var e,f=0,g=c;f<g.length;f++)if(e=g[f],!(e in b)||a[e]!==b[e])return!1;return!0}
@@ -1,5 +1,5 @@
1
1
  import type { CSSProperties } from 'react';
2
- import type { NodeInstance } from '../node.type.js';
2
+ import type { NodeElement, NodeInstance, Theme } from '../node.type.js';
3
3
  /**
4
4
  * Type guard to check if an object is a NodeInstance.
5
5
  *
@@ -12,21 +12,6 @@ import type { NodeInstance } from '../node.type.js';
12
12
  * @returns True if the object is a NodeInstance, false otherwise.
13
13
  */
14
14
  export declare const isNodeInstance: (obj: unknown) => obj is NodeInstance<any>;
15
- /**
16
- * Resolves theme variable references in an object's values recursively.
17
- * This function performs a "smart merge" to maintain object reference identity
18
- * for parts of the object that do not contain resolved theme variables or
19
- * other modifications. Only creates new objects or properties when a change occurs.
20
- * Handles nested objects and arrays, and prevents circular references.
21
- * Theme variables are referenced using the format "theme.path.to.value".
22
- * @param obj The object (or array) whose values should be resolved against the theme. Defaults to an empty object.
23
- * @param theme The theme object containing variable definitions. Optional.
24
- * @returns A new object (or array) with all theme variables resolved to their corresponding values,
25
- * or the original object (or array) if no changes were necessary.
26
- */
27
- export declare const resolveObjWithTheme: (obj?: Record<string, any>, theme?: Partial<{
28
- [key: string]: any;
29
- }> | undefined) => any;
30
15
  /**
31
16
  * Resolves default CSS styles to fix common flexbox layout issues.
32
17
  *
@@ -908,4 +893,25 @@ export declare const resolveDefaultStyle: (style: CSSProperties) => {
908
893
  minHeight: import("csstype").Property.MinHeight<string | number>;
909
894
  minWidth: import("csstype").Property.MinWidth<string | number>;
910
895
  };
896
+ /**
897
+ * Creates a stable hash string based on the provided children and optional theme.
898
+ *
899
+ * This function generates a hash that represents the structure and types of the given
900
+ * children nodes, along with an optional theme. The hash is designed to be stable across
901
+ * renders, meaning that the same input will always produce the same hash output.
902
+ *
903
+ * The hashing strategy includes:
904
+ * - For arrays of children, it includes the length and samples the types of the first few children.
905
+ * - For single child nodes, it includes the type of the node.
906
+ * - For primitive values (strings, numbers, etc.), it includes their type.
907
+ * - If a theme is provided, it includes a stringified version of the theme.
908
+ *
909
+ * This approach avoids deep traversal of potentially large or complex node trees,
910
+ * focusing instead on key characteristics that are likely to change when the structure
911
+ * or content changes.
912
+ * @param children The child nodes to hash, which can be a single node or an array of nodes.
913
+ * @param theme An optional theme object or string to include in the hash.
914
+ * @returns A stable hash string representing the structure and types of the children and theme.
915
+ */
916
+ export declare function createStableHash(children: NodeElement | NodeElement[], theme?: Theme): string;
911
917
  //# sourceMappingURL=node.helper.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"node.helper.d.ts","sourceRoot":"","sources":["../../src/helper/node.helper.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAC1C,OAAO,KAAK,EAAE,YAAY,EAAS,MAAM,mBAAmB,CAAA;AAG5D;;;;;;;;;;GAUG;AACH,eAAO,MAAM,cAAc,4CAS1B,CAAA;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB;;sBA+G/B,CAAA;AA+DD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiE/B,CAAA"}
1
+ {"version":3,"file":"node.helper.d.ts","sourceRoot":"","sources":["../../src/helper/node.helper.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAC1C,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAIzE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,cAAc,4CAS1B,CAAA;AA4DD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiE/B,CAAA;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,WAAW,GAAG,WAAW,EAAE,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,CA0B7F"}
@@ -1,4 +1,4 @@
1
- "use strict";var _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 _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)}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)}import{getValueByPath}from"./common.helper.js";/**
1
+ "use strict";var _excluded=["flex"];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 _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)}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 _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)}import{getElementTypeName}from"./common.helper.js";import{ObjHelper}from"./obj.helper.js";/**
2
2
  * Type guard to check if an object is a NodeInstance.
3
3
  *
4
4
  * A NodeInstance is expected to be a non-null object with:
@@ -9,32 +9,6 @@
9
9
  * @param obj The object to check.
10
10
  * @returns True if the object is a NodeInstance, false otherwise.
11
11
  */export var isNodeInstance=function isNodeInstance(a){return"object"===_typeof(a)&&null!==a&&"element"in a&&"function"==typeof a.render&&"function"==typeof a.toPortal&&"isBaseNode"in a};/**
12
- * Resolves theme variable references in an object's values recursively.
13
- * This function performs a "smart merge" to maintain object reference identity
14
- * for parts of the object that do not contain resolved theme variables or
15
- * other modifications. Only creates new objects or properties when a change occurs.
16
- * Handles nested objects and arrays, and prevents circular references.
17
- * Theme variables are referenced using the format "theme.path.to.value".
18
- * @param obj The object (or array) whose values should be resolved against the theme. Defaults to an empty object.
19
- * @param theme The theme object containing variable definitions. Optional.
20
- * @returns A new object (or array) with all theme variables resolved to their corresponding values,
21
- * or the original object (or array) if no changes were necessary.
22
- */export var resolveObjWithTheme=function resolveObjWithTheme(){var a=0<arguments.length&&arguments[0]!==void 0?arguments[0]:{},b=1<arguments.length?arguments[1]:void 0;if(!b||!!b&&"object"===_typeof(b)&&0===Object.keys(b).length||0===Object.keys(a).length)return a;/**
23
- * Recursively resolves theme variables within an object or array.
24
- * It tracks visited objects to prevent infinite recursion caused by circular references.
25
- * This function implements a "smart merge" to preserve object/array identity for unchanged parts.
26
- * @param currentObj The current object or array being processed in the recursion.
27
- * @param visited A Set to keep track of objects that have already been visited to detect circular references.
28
- * @returns The processed object/array with theme variables resolved, or the original `currentObj`
29
- * if no changes were made to it or its direct children (excluding deeper nested changes).
30
- */var c=function resolveRecursively(a,d){// Base cases for non-objects/null, or already visited objects (circular reference)
31
- if(null===a||"object"!==_typeof(a))return a;if(d.has(a))return a;// Handle Arrays
32
- if(d.add(a),Array.isArray(a)){for(var e=a,f=!1,g=0;g<a.length;g++){var h=a[g],j=c(h,d);j===h?f&&(e[g]=h):(!f&&(e=[...a],f=!0),e[g]=j)}return e}// Handle Plain Objects (only process objects created with {})
33
- var k=a,l=!1,m=function _loop(){// Ensure it's an own property
34
- var e=a[n],f=e;if("function"==typeof e||"object"===_typeof(e)&&null!==e&&!Array.isArray(e)&&Object.getPrototypeOf(e)!==Object.prototype||// Exclude plain objects and arrays
35
- "object"!==_typeof(e)&&"string"!=typeof e)f=e;else if("string"==typeof e&&e.includes("theme.")){var g=e,h=!1;g=g.replace(/theme\.([a-zA-Z0-9_.-]+)/g,function(a,c){var d=getValueByPath(b,c);return void 0!==d&&null!==d?(h=!0,"object"===_typeof(d)&&!Array.isArray(d)&&"default"in d?d["default"]:d):a}),f=h&&g!==e?g:e}else"object"===_typeof(e)&&null!==e&&(// Recursively process nested objects or arrays
36
- f=c(e,d));f===e?l&&(k[n]=e):(!l&&(k=_objectSpread({},a),l=!0),k[n]=f)};for(var n in a)m();return k};// Initial call, ensure `obj` could be an array as well
37
- return c(a,new Set)};/**
38
12
  * Parsed flex shorthand components for CSS flex property
39
13
  * @interface FlexComponents
40
14
  * @property grow - The flex-grow value (how much the item should grow)
@@ -59,8 +33,7 @@ return c(a,new Set)};/**
59
33
  * parseFlexShorthand('1 0 auto') // → {grow: 1, shrink: 0, basis: 'auto'}
60
34
  */function parseFlexShorthand(a){// Early returns for invalid inputs
61
35
  if(null===a||a===void 0)return null;// Handle numeric flex values (e.g., flex: 1)
62
- if("number"==typeof a)return{grow:a,shrink:1,basis:"0%"};// Only process string values
63
- if("string"!=typeof a)return null;var b=a.trim().toLowerCase();if(!b)return null;// Handle CSS keyword values
36
+ if("number"==typeof a)return{grow:a,shrink:1,basis:"0%"};var b=a.trim().toLowerCase();if(!b)return null;// Handle CSS keyword values
64
37
  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}/**
65
38
  * Resolves default CSS styles to fix common flexbox layout issues.
66
39
  *
@@ -136,4 +109,23 @@ if(!f){var k="column"===d.flexDirection||"column-reverse"===d.flexDirection,l="r
136
109
  return _objectSpread({flex:c,// Preserve original flex shorthand
137
110
  flexShrink:j,// Apply computed or explicit flexShrink
138
111
  minHeight:0,// Fix flex item scrolling issues
139
- minWidth:0},d)};
112
+ minWidth:0},d)};/**
113
+ * Creates a stable hash string based on the provided children and optional theme.
114
+ *
115
+ * This function generates a hash that represents the structure and types of the given
116
+ * children nodes, along with an optional theme. The hash is designed to be stable across
117
+ * renders, meaning that the same input will always produce the same hash output.
118
+ *
119
+ * The hashing strategy includes:
120
+ * - For arrays of children, it includes the length and samples the types of the first few children.
121
+ * - For single child nodes, it includes the type of the node.
122
+ * - For primitive values (strings, numbers, etc.), it includes their type.
123
+ * - If a theme is provided, it includes a stringified version of the theme.
124
+ *
125
+ * This approach avoids deep traversal of potentially large or complex node trees,
126
+ * focusing instead on key characteristics that are likely to change when the structure
127
+ * or content changes.
128
+ * @param children The child nodes to hash, which can be a single node or an array of nodes.
129
+ * @param theme An optional theme object or string to include in the hash.
130
+ * @returns A stable hash string representing the structure and types of the children and theme.
131
+ */export function createStableHash(a,b){var c=Math.min,d="";if(b&&(d+="t:".concat("object"===_typeof(b)?ObjHelper.stringify(b):b+"",";")),Array.isArray(a)){d+="a:".concat(a.length,";");for(var e,f=c(3,a.length),g=0;g<f;g++)e=a[g],d+=e&&"object"===_typeof(e)&&"type"in e?"c".concat(g,":").concat(getElementTypeName(e.type),";"):"c".concat(g,":").concat(_typeof(e),";")}else d+=a&&"object"===_typeof(a)&&"type"in a?"s:".concat(getElementTypeName(a.type),";"):"s:".concat(_typeof(a),";");return d}
@@ -0,0 +1,6 @@
1
+ export declare class ObjHelper {
2
+ private constructor();
3
+ static stringify(obj: any, space?: number): string;
4
+ static parse(str: string): any;
5
+ }
6
+ //# sourceMappingURL=obj.helper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"obj.helper.d.ts","sourceRoot":"","sources":["../../src/helper/obj.helper.ts"],"names":[],"mappings":"AAWA,qBAAa,SAAS;IACpB,OAAO,eAAiB;IAExB,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,SAAI,GAAG,MAAM,CAiD5C;IAED,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CA+C7B;CACF"}
@@ -0,0 +1 @@
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)}export class ObjHelper{constructor(){}static stringify(a){var b=1<arguments.length&&arguments[1]!==void 0?arguments[1]:2,c=new Map,d=new Map,e=0,f=0,g=function replacer(a,b){if("function"==typeof b)return d.has(b)||d.set(b,f++),{$type:"Function",name:b.name||"",id:d.get(b)};if("symbol"===_typeof(b)){var g;return{$type:"Symbol",key:null!==(g=b.description)&&void 0!==g?g:""}}if("bigint"==typeof b)return{$type:"BigInt",value:b.toString()};if(b instanceof Date)return{$type:"Date",value:b.toISOString()};if(b instanceof RegExp)return{$type:"RegExp",source:b.source,flags:b.flags};if(b instanceof Map)return{$type:"Map",entries:Array.from(b.entries())};if(b instanceof Set)return{$type:"Set",values:Array.from(b.values())};if("object"===_typeof(b)&&null!==b){if(c.has(b))return{$type:"Circular",ref:c.get(b)};c.set(b,e++)}return b};return JSON.stringify(a,g,b)}static parse(a){var b=[],c=function reviver(a,b){if(b&&"object"===_typeof(b)&&"$type"in b)switch(b.$type){case"Function":return function FunctionPlaceholder(){throw new Error("Function placeholder called: ".concat(b.name||"anonymous","#").concat(b.id))};case"Symbol":return Symbol(b.key);case"BigInt":return BigInt(b.value);case"Date":return new Date(b.value);case"RegExp":return new RegExp(b.source,b.flags);case"Map":return new Map(b.entries);case"Set":return new Set(b.values);case"Circular":return{$circularRef:b.ref}}return b},d=JSON.parse(a,c),e=function fixCirculars(a){if(a&&"object"===_typeof(a)){if(a.$circularRef!==void 0)return b[a.$circularRef];if(!b.includes(a)){b.push(a);for(var c,d=0,f=Object.keys(a);d<f.length;d++)c=f[d],a[c]=e(a[c])}}return a};return e(d)}}