UNPKG

@meonode/ui

Version:

A structured approach to component composition with built-in theming, prop separation, and dynamic children handling.

128 lines 6.52 kB
import { type ReactNode } from 'react'; import type { FinalNodeProps, NodeElement, NodeInstance, NodeProps, RawNodeProps, Theme } from './node.type.js'; import { type Root as ReactDOMRoot } from 'react-dom/client'; /** * Represents a node in a React component tree with theme and styling capabilities. * This class wraps React elements and handles: * - Props processing and normalization * - Theme inheritance and resolution * - Child node processing and management * - Style processing with theme variables * @template E The type of React element or component this node represents */ export declare class BaseNode<E extends NodeElement = NodeElement> implements NodeInstance<E> { /** The underlying React element or component type that this node represents */ element: E; /** Original props passed during construction, preserved for cloning/recreation */ rawProps: RawNodeProps<E>; /** Processed props after theme resolution, style processing, and child normalization */ props: FinalNodeProps; readonly isBaseNode = true; private _portalDOMElement; private _portalReactRoot; /** * Creates a new BaseNode instance that wraps a React element. * Processes raw props by: * - Extracting and resolving theme-aware styles * - Processing DOM-related props * - Normalizing children with theme inheritance * @param element The React element/component to wrap * @param rawProps Initial props including theme, styles, and children */ constructor(element: E, rawProps?: RawNodeProps<E>); /** * Resolves default styles for a given CSSProperties object. * This method ensures that certain default styles, such as `minHeight`, `minWidth`, * and `flexShrink`, are applied based on the provided style properties. * * - If the element is a flex container: * - Sets `flexShrink` to 0 for specific scenarios: * - Column-based layout without wrapping. * - Row-based layout without wrapping (a default direction is assumed to be 'row'). * - If the element is not a flex container: * - Defaults `flexShrink` to 0. * @param style The CSSProperties object containing style definitions. * @returns An object with resolved default styles. */ private _resolveDefaultStyle; /** * Resolves theme variable references in an object's values recursively. * Handles nested objects and prevents circular references. * Theme variables are referenced using the format "theme.path.to.value". * @param obj The object whose values should be resolved against the theme * @param theme Optional theme object containing variable definitions * @returns A new object with all theme variables resolved to their values */ private _resolveObjWithTheme; /** * Renders a processed NodeElement into a ReactNode, applying theme and key if needed. * * Handles the following cases: * 1. If the element is a BaseNode instance, it re-wraps it to apply the key and theme if needed. * 2. If the element is a React class component type, it wraps it in a BaseNode. * 3. If the element is a NodeInstance object, it calls its render method. * 4. If the element is a React.Component instance, it calls its render method. * 5. If the element is a functional component, it creates a React element with the provided key. * 6. For all other valid ReactNode types, it returns the element as-is. * @param processedElement The processed node element to render. * @param passedTheme The theme to apply, if any. * @param passedKey The key to assign, if any. * @returns The rendered ReactNode. */ private _renderProcessedNode; /** * Renders the result of a function child, supporting theme propagation. * * Used for children that are functions (`() => Children`). If the returned value is a `BaseNode` * without an explicit theme, the parent theme is injected. Otherwise, the result is rendered as-is. * @template E - The type of ReactNode or NodeInstance. * @param props Renderer props. * @param props.render Function to invoke for rendering the child. * @param props.passedTheme Theme to provide to the child, if applicable. * @param props.passedKey Key to assign to the rendered node. * @param props.processRawNode Function to process raw nodes. * @returns The rendered ReactNode, with theme applied if necessary. */ private _functionRenderer; /** * Processes a single raw child element, converting it into a ProcessedChild. * If the child is part of an array and lacks an explicit key, a stable indexed key * (`elementName_child_index`) is generated for new BaseNode instances. * @param rawNode The raw child element to process. * @param parentTheme The theme inherited from the parent node. * @param childIndex Optional index of the child if it's part of an array. * @returns The processed child. */ _processRawNode(rawNode: NodeElement, parentTheme?: Theme, childIndex?: number): NodeElement; /** * Normalizes a child node into a renderable ReactNode. * Processes different types of child nodes to ensure they can be properly rendered * while maintaining theme inheritance. * * Handles: * - BaseNode instances (applies theme if needed) * - React.Component instances (applies theme if needed) * - Other valid React element types (returned as-is) * - null/undefined values (returned as-is) * @param child The child node to normalize into a renderable form * @returns The normalized ReactNode that can be rendered by React * @throws Error if child is an invalid element type */ private _normalizeChild; /** * Converts this BaseNode instance into a renderable React node. * Recursively processes child nodes and uses `React.createElement` to construct the final React element. * @returns A ReactNode representing the rendered element. */ render(): ReactNode; private _ensurePortalInfrastructure; toPortal(): ReactDOMRoot | null; } /** * Factory function to create a BaseNode instance. * @param element The React element type. * @param props The props for the node. * @returns NodeInstance<E> - A new BaseNode instance. */ export declare function Node<E extends NodeElement>(element: E, props?: Partial<NodeProps<E>>): NodeInstance<E>; //# sourceMappingURL=core.node.d.ts.map