UNPKG

@meonode/ui

Version:

A structured approach to component composition, direct CSS-first prop styling, built-in theming, smart prop handling (including raw property pass-through), and dynamic children.

2 lines (1 loc) 6.93 kB
"use strict";var e=require("react"),t=require("../helper/react-is.helper.cjs"),r=require("../helper/common.helper.cjs"),o=require("../constant/common.const.cjs"),n=require("../core.node.cjs");const s=Symbol.for("@meonode/ui/NodeUtil/functionSignatureCache");class i{constructor(){}static readBooleanFlag(e,t){if("function"!=typeof e)return!1;try{return!0===e[t]}catch{return!1}}static isServer="undefined"==typeof window;static get _functionSignatureCache(){return r.getGlobalState(s,()=>new WeakMap)}static CRITICAL_PROPS=new Set(["css","className","disableEmotion","props"]);static _propFuncCache=new WeakMap;static isClientReference(e){if(!e||"object"!=typeof e&&"function"!=typeof e)return!1;try{return e.$$typeof===Symbol.for("react.client.reference")}catch{return!1}}static acceptsServerCss(e){return i.readBooleanFlag(e,"__meonodeAcceptsServerCss")}static providesServerTheme(e){return i.readBooleanFlag(e,"__meonodeProvidesServerTheme")}static isNodeInstance=e=>e instanceof n.BaseNode;static isStyleProp=i.isServer||"undefined"==typeof document?()=>!1:e=>e in document.body.style;static hashString(e){let t=2166136261,r=5381;for(let o=0;o<e.length;o++){const n=e.charCodeAt(o);t^=n,t=Math.imul(t,16777619),r=Math.imul(r,33)^n}return`${(t>>>0).toString(36)}_${(r>>>0).toString(36)}`}static hashCSS(e){const t=Object.keys(e);let r=t.length;for(let o=0;o<Math.min(t.length,10);o++){const n=t[o],s=e[n];r=(r<<5)-r+n.charCodeAt(0),r&=r,"string"==typeof s&&(r=(r<<5)-r+s.length)}return r.toString(36)}static createPropSignature(e,t){if(i.isServer)return;const o=r.getElementTypeName(e),n=Object.keys(t);n.length>1&&n.sort();const s=[`${o}:`];if("function"==typeof e){let t=i._functionSignatureCache.get(e);t||(t=i.hashString(e.toString()),i._functionSignatureCache.set(e,t)),s.push(t)}for(const e of n){const r=t[e];let o;const n=typeof r;if("string"===n||"number"===n||"boolean"===n)o=`${e}:${r};`;else if(null===r)o=`${e}:null;`;else if(void 0===r)o=`${e}:undefined;`;else if("css"===e&&"object"==typeof r)o=`css:${this.hashCSS(r)};`;else if(Array.isArray(r)){const t=r.filter(e=>{const t=typeof e;return"string"===t||"number"===t||"boolean"===t||null===e});o=t.length===r.length?`${e}:[${t.join(",")}];`:`${e}:[${r.length}];`}else if(r&&r.isBaseNode)o=`${e}:${r.stableKey};`;else if("function"===n){let t=i._propFuncCache.get(r);t||(t=i.hashString(r.toString()),i._propFuncCache.set(r,t)),o=`${e}:${t};`}else{o=`${e}:{${Object.keys(r).sort().join(",")}};`}s.push(o)}return i.hashString(s.join(","))}static extractCriticalProps(e,t){const r={_keyCount:t.length};let o=0;for(const n of t){if(o>=50)break;if(i.CRITICAL_PROPS.has(n)){r[n]=e[n],o++;continue}const s=n.charCodeAt(0);111!==s||110!==n.charCodeAt(1)?!(97===s&&114===n.charCodeAt(1)&&105===n.charCodeAt(2)&&97===n.charCodeAt(3)||100===s&&97===n.charCodeAt(1)&&116===n.charCodeAt(2)&&97===n.charCodeAt(3))?t.length<=100&&i.isStyleProp(n)&&(r[n]=e[n],o++):(r[n]=e[n],o++):(r[n]=e[n],o++)}return r}static processProps(e={},t){const{ref:o,key:n,children:s,css:c,props:a={},disableEmotion:d,...l}=e;if(0===Object.keys(l).length&&!c)return r.omitUndefined({ref:o,key:n,disableEmotion:d,nativeProps:r.omitUndefined(a),children:i._processChildren(s,d)});const f={},p={},u=Object.keys(l);for(let e=0;e<u.length;e++){const t=u[e],r=l[t],o=typeof r;"string"===o||"number"===o||"boolean"===o?f[t]=r:p[t]=r}const y=r.getCSSProps(f),m=r.getCSSProps(p),h=r.getDOMProps(l),b={...y,...m,...c},g=i._processChildren(s,d,t);return r.omitUndefined({ref:o,key:n,css:b,...h,disableEmotion:d,nativeProps:r.omitUndefined(a),children:g})}static _processChildren(e,t,r){if(e)return"function"==typeof e?e:Array.isArray(e)?1===e.length?i.processRawNode(e[0],t,`${r}_0`):e.map((e,o)=>i.processRawNode(e,t,`${r}_${o}`)):i.processRawNode(e,t,r)}static shouldCacheElement(e){return!i.isServer&&!!e.stableKey&&!!e.dependencies}static shouldNodeUpdate(e,t,r){if(i.isServer)return!0;if(r)return!1;if(void 0===t)return!0;if(void 0===e)return!0;if(t.length!==e.length)return!0;for(let r=0;r<t.length;r++)if(!Object.is(t[r],e[r]))return!0;return!1}static processRawNode(r,o,s){if(null==r||"string"==typeof r||"number"==typeof r||"boolean"==typeof r)return r;if(i.isNodeInstance(r)){if(s||o&&!r.rawProps.disableEmotion){const e=new n.BaseNode(r.element,r.rawProps,r.dependencies);return e.stableKey=`${s}:${e.stableKey}`,o&&!e.rawProps.disableEmotion&&(e.rawProps.disableEmotion=!0),e}return r}if(i.isFunctionChild(r))return new n.BaseNode(i.functionRenderer,{props:{render:r,disableEmotion:o}},void 0);if(e.isValidElement(r)){const e=r.type;if(e&&"object"==typeof e){const t=e.$$typeof;if(t===Symbol.for("react.client.reference")||t===Symbol.for("react.lazy")||t===Symbol.for("react.memo")||t===Symbol.for("react.forward_ref"))return r}if("string"==typeof r.type){const{style:e,...t}=r.props,s={...t,...e||{}};return new n.BaseNode(r.type,{...s,...null!==r.key&&void 0!==r.key?{key:r.key}:{},disableEmotion:o},void 0)}return new n.BaseNode(r.type,{...r.props,...null!==r.key&&void 0!==r.key?{key:r.key}:{},disableEmotion:o},void 0)}return t.isReactClassComponent(r)||t.isMemo(r)||t.isForwardRef(r)?new n.BaseNode(r,{disableEmotion:o},void 0):r instanceof e.Component?i.processRawNode(r.render(),o,s):r}static isFunctionChild(e){if("function"!=typeof e||t.isReactClassComponent(e)||t.isMemo(e)||t.isForwardRef(e))return!1;try{return!(e.prototype&&"function"==typeof e.prototype.render)}catch(e){return o.__DEBUG__&&console.error("MeoNode: Error checking if a node is a function child.",e),!0}}static functionRenderer({render:t,disableEmotion:s}){let c;try{c=t()}catch(e){o.__DEBUG__&&console.error("MeoNode: Error executing function-as-a-child.",e),c=null}if(null==c||"string"==typeof c||"number"==typeof c||"boolean"==typeof c)return c;if(i.isNodeInstance(c))return s&&!c.rawProps.disableEmotion?new n.BaseNode(c.element,{...c.rawProps,disableEmotion:!0}).render():c.render();if(Array.isArray(c)){const e=(e,t)=>{try{return`${r.getElementTypeName(e)}-${t}`}catch(e){return o.__DEBUG__&&console.error("MeoNode: Could not determine element type name for key in function-as-a-child.",e),`item-${t}`}};return c.map((t,r)=>i.renderProcessedNode({processedElement:i.processRawNode(t,s),passedKey:e(t,r),disableEmotion:s}))}if(c instanceof e.Component)return i.renderProcessedNode({processedElement:i.processRawNode(c.render(),s),disableEmotion:s});const a=i.processRawNode(c,s);return a?i.renderProcessedNode({processedElement:a,disableEmotion:s}):c}static renderProcessedNode({processedElement:r,passedKey:o,disableEmotion:s}){const c={};if(void 0!==o&&(c.key=o),i.isNodeInstance(r)){const e=r.rawProps?.key;return r.rawProps.disableEmotion=s,e===o?r.render():new n.BaseNode(r.element,{...r.rawProps,...c}).render()}return t.isReactClassComponent(r)?new n.BaseNode(r,{...c,disableEmotion:s}).render():r instanceof e.Component?r.render():"function"==typeof r?e.createElement(r,{key:o}):r}}exports.NodeUtil=i;