@meonode/ui 0.1.17 → 0.1.19

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/README.md CHANGED
@@ -161,98 +161,268 @@ const Dashboard = Component(() =>
161
161
  );
162
162
  ```
163
163
 
164
+ ### Material UI Integration
165
+
166
+ ```shell
167
+ yarn add @meonode/mui @mui/material
168
+ ```
169
+
170
+ ```ts
171
+ import { Button, TextField } from '@meonode/mui';
172
+
173
+ const MuiLoginForm = Component(() =>
174
+ Div({
175
+ maxWidth: '400px',
176
+ margin: '0 auto',
177
+ children: [
178
+ TextField({
179
+ label: 'Email',
180
+ fullWidth: true,
181
+ margin: 'normal'
182
+ }),
183
+ TextField({
184
+ label: 'Password',
185
+ type: 'password',
186
+ fullWidth: true,
187
+ margin: 'normal'
188
+ }),
189
+ Button({
190
+ variant: 'contained',
191
+ color: 'primary',
192
+ children: 'Sign In'
193
+ })
194
+ ]
195
+ })
196
+ );
197
+ ```
198
+
164
199
  ### With Conditional Children That Contains Hook
165
200
 
166
201
  ```ts
167
202
  'use client'
168
203
  /**
169
- * This file demonstrates integration between React hooks and BaseNode components
170
- * using the @meonode/ui library for declarative UI construction.
171
- * It explores various rendering patterns, Higher-Order Component (HOC) usage,
172
- * and theme propagation with @meonode/ui components.
204
+ * This file showcases the integration of React hooks with @meonode/ui components
205
+ * for building declarative user interfaces. It demonstrates different rendering
206
+ * approaches, the use of Higher-Order Components (HOCs), and how theme context
207
+ * is managed and propagated within the @meonode/ui component tree.
173
208
  */
174
- import { Component, Column, Row, Div, P, Node } from '@meonode/ui' // Theme type is not explicitly imported or used as a prop type in this file's components.
175
- import { useState, useEffect } from 'react'
176
- import { CssBaseline, TextField } from '@meonode/mui'
209
+ import { Component, Column, Row, P, Node, Button, Theme, Center, NodeInstance } from '@meonode/ui'
210
+ import { useState, useEffect, ReactElement, ReactNode } from 'react'
211
+ import { CssBaseline, FormControlLabel, TextField } from '@meonode/mui'
212
+ import { Switch as MUISwitch } from '@mui/material'
213
+ import { styled } from '@mui/material'
214
+
215
+ const MaterialUISwitch = styled(MUISwitch)(({ theme }) => ({
216
+ width: 62,
217
+ height: 34,
218
+ padding: 7,
219
+ '& .MuiSwitch-switchBase': {
220
+ margin: 1,
221
+ padding: 0,
222
+ transform: 'translateX(6px)',
223
+ '&.Mui-checked': {
224
+ color: '#fff',
225
+ transform: 'translateX(22px)',
226
+ '& .MuiSwitch-thumb:before': {
227
+ backgroundImage: `url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="20" width="20" viewBox="0 0 20 20"><path fill="${encodeURIComponent(
228
+ '#fff',
229
+ )}" d="M4.2 2.5l-.7 1.8-1.8.7 1.8.7.7 1.8.6-1.8L6.7 5l-1.9-.7-.6-1.8zm15 8.3a6.7 6.7 0 11-6.6-6.6 5.8 5.8 0 006.6 6.6z"/></svg>')`,
230
+ },
231
+ '& + .MuiSwitch-track': {
232
+ opacity: 1,
233
+ backgroundColor: '#aab4be',
234
+ ...theme.applyStyles('dark', {
235
+ backgroundColor: '#8796A5',
236
+ }),
237
+ },
238
+ },
239
+ },
240
+ '& .MuiSwitch-thumb': {
241
+ backgroundColor: '#001e3c',
242
+ width: 32,
243
+ height: 32,
244
+ '&::before': {
245
+ content: "''",
246
+ position: 'absolute',
247
+ width: '100%',
248
+ height: '100%',
249
+ left: 0,
250
+ top: 0,
251
+ backgroundRepeat: 'no-repeat',
252
+ backgroundPosition: 'center',
253
+ backgroundImage: `url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="20" width="20" viewBox="0 0 20 20"><path fill="${encodeURIComponent(
254
+ '#fff',
255
+ )}" d="M9.305 1.667V3.75h1.389V1.667h-1.39zm-4.707 1.95l-.982.982L5.09 6.072l.982-.982-1.473-1.473zm10.802 0L13.927 5.09l.982.982 1.473-1.473-.982-.982zM10 5.139a4.872 4.872 0 00-4.862 4.86A4.872 4.872 0 0010 14.862 4.872 4.872 0 0014.86 10 4.872 4.872 0 0010 5.139zm0 1.389A3.462 3.462 0 0113.471 10a3.462 3.462 0 01-3.473 3.472A3.462 3.462 0 016.527 10 3.462 3.462 0 0110 6.528zM1.665 9.305v1.39h2.083v-1.39H1.666zm14.583 0v1.39h2.084v-1.39h-2.084zM5.09 13.928L3.616 15.4l.982.982 1.473-1.473-.982-.982zm9.82 0l-.982.982 1.473 1.473.982-.982-1.473-1.473zM9.305 16.25v2.083h1.389V16.25h-1.39z"/></svg>')`,
256
+ },
257
+ ...theme.applyStyles('dark', {
258
+ backgroundColor: '#003892',
259
+ }),
260
+ },
261
+ '& .MuiSwitch-track': {
262
+ opacity: 1,
263
+ backgroundColor: '#aab4be',
264
+ borderRadius: 20 / 2,
265
+ ...theme.applyStyles('dark', {
266
+ backgroundColor: '#8796A5',
267
+ }),
268
+ },
269
+ }))
177
270
 
178
271
  /**
179
- * Global theme configuration.
180
- * Contains color palette definitions used by @meonode/ui components
181
- * when they resolve theme strings from context.
182
- * This can be extracted to a separate theme file for larger applications.
272
+ * Defines the color palette for the light theme.
273
+ * These color values are used by @meonode/ui components when they encounter
274
+ * theme string references (e.g., 'theme.primary') and the current theme mode is 'light'.
275
+ * In a larger application, this theme object would typically reside in a dedicated theme file.
183
276
  */
184
- const theme = {
185
- background: { primary: 'lightgreen', secondary: 'lightyellow' },
277
+ const lightTheme: Theme = {
278
+ mode: 'light',
279
+ colors: {
280
+ primary: '#2563eb',
281
+ secondary: '#64748b',
282
+ accent: '#10b981',
283
+ background: '#ffffff',
284
+ foreground: '#0f172a',
285
+ border: '#e2e8f0',
286
+ muted: '#f8fafc',
287
+ success: '#16a34a',
288
+ warning: '#eab308',
289
+ danger: '#dc2626',
290
+ },
186
291
  }
187
292
 
188
293
  /**
189
- * The page's main logic is defined as a function (which may use React hooks).
190
- * This function is wrapped in the `Component` HOC from @meonode/ui.
191
- * The HOC standardizes it as a React component, ensuring it returns a ReactNode.
192
- * This makes the component compatible with React's rendering process,
193
- * supporting both client-side and server-side rendering.
294
+ * Defines the color palette for the dark theme.
295
+ * Similar to the light theme, these colors are used by @meonode/ui components
296
+ * when resolving theme string references, but specifically when the current theme
297
+ * mode is 'dark'.
298
+ */
299
+ const darkTheme: Theme = {
300
+ mode: 'dark',
301
+ colors: {
302
+ primary: '#3b82f6',
303
+ secondary: '#94a3b8',
304
+ accent: '#34d399',
305
+ background: '#0f172a',
306
+ foreground: '#f8fafc',
307
+ border: '#334155',
308
+ muted: '#1e293b',
309
+ success: '#22c55e',
310
+ warning: '#facc15',
311
+ danger: '#ef4444',
312
+ },
313
+ }
314
+
315
+ /**
316
+ * The main page component, implemented as a functional component using React hooks.
317
+ * It manages the theme mode state and the visibility of additional content.
318
+ *
319
+ * This function is wrapped by the `Component` HOC from `@meonode/ui`. The `Component`
320
+ * HOC transforms the function into a standard React component that returns a `ReactNode`,
321
+ * making it compatible with React's rendering lifecycle and enabling SSR/CSR.
194
322
  */
195
323
  export default Component(() => {
196
324
  // State hook to control the visibility of additional content sections.
197
325
  const [showMore, setShowDetails] = useState(false) // 'showMore' controls visibility, 'setShowDetails' is the updater.
326
+ const [mode, setMode] = useState<'dark' | 'light'>('light')
327
+ const theme = mode === 'dark' ? darkTheme : lightTheme
198
328
 
199
329
  /**
200
- * The main layout is structured as a Column.
201
- * It includes:
202
- * - A header row with a button to toggle the visibility of additional content.
203
- * - A series of examples demonstrating different ways to render detail components,
330
+ * The root of the UI tree is a `Column` component from `@meonode/ui`.
331
+ * This `Column` sets the theme context for its children.
332
+ * Its children include:
333
+ * - A theme toggle switch using MUI components wrapped in `@meonode/ui`'s `Node`.
334
+ * - A button to toggle the visibility of the detail sections.
335
+ * - Various examples demonstrating how to render components that return either
336
+ * `@meonode/ui` `Node` instances or `ReactNode`s, illustrating theme propagation
204
337
  * both unconditionally and conditionally, highlighting theme propagation.
205
338
  */
206
339
  return Column({
207
- theme, // Provide the global theme to the Column and its descendants via React context.
340
+ theme: theme.colors,
208
341
  padding: 20,
209
342
  gap: 15,
343
+ minHeight: '100vh',
344
+ backgroundColor: 'theme.background',
345
+ color: 'theme.foreground',
210
346
  children: [
211
- CssBaseline, // Applies baseline MUI styles.
212
- // Interactive header section for toggling more content.
213
- Row({
214
- gap: 10,
215
- children: [
216
- Div({
217
- onClick: () => setShowDetails(prev => !prev), // Click handler to toggle the 'showMore' state.
218
- cursor: 'pointer', // Visual cue for clickability.
219
- userSelect: 'none', // Prevents text selection on the button.
220
- padding: '10px 20px',
221
- backgroundColor: 'theme.background.primary', // Background color sourced from the theme context.
222
- borderRadius: 5,
223
- fontWeight: 'bold',
224
- children: showMore ? 'Hide' : 'Show More', // Dynamically sets button text based on 'showMore' state.
225
- }),
226
- ],
347
+ // Theme toggle switch using MUI components wrapped with @meonode/ui's Node HOC.
348
+ Center({
349
+ children: FormControlLabel({
350
+ control: Node(MaterialUISwitch).render() as ReactElement,
351
+ alignItems: 'center',
352
+ label: mode === 'dark' ? 'Dark Mode' : 'Light Mode',
353
+ labelPlacement: 'start',
354
+ checked: mode === 'dark',
355
+ onChange: () => setMode(prev => (prev === 'dark' ? 'light' : 'dark')),
356
+ }),
357
+ }),
358
+ // Button to toggle the visibility of the detail sections.
359
+ Button(showMore ? 'Hide' : 'Show More', {
360
+ onClick: () => setShowDetails(prev => !prev), // Click handler to toggle the 'showMore' state.
361
+ cursor: 'pointer', // Visual cue for clickability.
362
+ userSelect: 'none', // Prevents text selection on the button.
363
+ padding: '10px 20px',
364
+ backgroundColor: 'theme.accent', // Background color sourced from the theme context.
365
+ borderRadius: 5,
366
+ fontWeight: 'bold',
367
+ color: 'white',
227
368
  }),
369
+ CssBaseline, // Applies baseline Material UI styles for consistent rendering.
228
370
 
229
371
  /**
230
- * Unconditional rendering examples:
231
- * Demonstrates rendering DetailComponent (returns a @meonode/ui Node instance) and
232
- * ReturnRenderedDetailComponent (returns a ReactNode), and usage of the Node HOC.
233
- * Pay attention to how theme is (or isn't) propagated to these components.
372
+ * --- Unconditional Rendering Examples ---
373
+ * These examples demonstrate rendering components that return either a
374
+ * `@meonode/ui` `Node` instance (`DetailComponent`) or a `ReactNode`
375
+ * (`ReturnRenderedDetailComponent`), and how the `Node` HOC affects this.
376
+ * Observe how theme context is propagated (or not) in each case.
234
377
  */
235
- DetailComponent({ info: 'Here are some details 1!' }), // Renders DetailComponent; its internal Row sources theme from parent Column's context.
236
- DetailComponent({ info: 'Here are some details 2!' }).render(), // Renders DetailComponent (invoking .render()); its internal Row sources theme from parent Column's context.
237
- // Node(DetailComponent, { info: 'Here are some details 3!' }), // ❌ Fails: Node HOC expects its first argument (a component function) to return ReactNode. DetailComponent returns a @meonode/ui Node instance.
378
+ // 1. Rendering a component that returns a @meonode/ui Node instance directly.
379
+ // The internal Row component correctly receives theme context from the parent Column.
380
+ DetailComponent({ info: 'Detail 1 (Node instance)' }),
381
+
382
+ // 2. Rendering a component that returns a @meonode/ui Node instance, then calling .render().
383
+ // The internal Row component also correctly receives theme context.
384
+ DetailComponent({ info: 'Detail 2 (Node instance + .render())' }).render(),
385
+
386
+ // 3. Attempting to wrap a component returning a Node instance with Node HOC.
387
+ // ❌ Fails: The Node HOC expects the wrapped function to return a ReactNode, not a @meonode/ui Node instance.
388
+ // Node(DetailComponent, { info: 'Detail 3 (Node HOC on Node instance)' }),
389
+
390
+ // 4. Rendering a component that explicitly returns a ReactNode (.render() is called internally).
391
+ // The internal Row component correctly receives theme context from the parent Column.
392
+ ReturnRenderedDetailComponent({ info: 'Detail 4 (ReactNode)' }),
393
+
394
+ // 5. Wrapping a component returning ReactNode with Node HOC.
395
+ // Renders successfully. However, the Node HOC does NOT propagate theme context to the wrapped component's children.
396
+ Node(ReturnRenderedDetailComponent, { info: 'Detail 5 (Node HOC on ReactNode)' }),
238
397
 
239
- ReturnRenderedDetailComponent({ info: 'Here are some details 4!' }), // Renders ReturnRenderedDetailComponent; its internal Row inherits theme from parent Column's context.
240
- Node(ReturnRenderedDetailComponent, { info: 'Here are some details 5!' }), // Node HOC with a function returning ReactNode: Renders. Theme from Column is NOT propagated by Node HOC to the internal Row.
241
- Node(ReturnRenderedDetailComponent, { info: 'Here are some details 6!' }).render(), // Node HOC (then .render()): Renders. Theme from Column is NOT propagated by Node HOC to the internal Row.
242
- // Node(DetailComponent, { info: 'Here are some details 7!' }).render(), // ❌ Fails: Same reason as above; Node HOC expects a function returning ReactNode.
398
+ // 6. Wrapping a component returning ReactNode with Node HOC, then calling .render().
399
+ // Renders successfully. Theme context is NOT propagated by the Node HOC.
400
+ Node(ReturnRenderedDetailComponent, { info: 'Detail 6 (Node HOC on ReactNode + .render())' }).render(),
243
401
 
244
402
  /**
245
403
  * Conditional rendering examples (shown when 'showMore' is true):
246
404
  * These demonstrate various wrapping techniques (inline functions, Component HOC)
247
405
  * and their effect on rendering and theme propagation for both types of detail components.
248
406
  */
249
- showMore && (() => DetailComponent({ info: 'Here are some details 8!' })), // Method 1 (inline function wrapper): Renders DetailComponent; its internal Row sources theme from context.
250
- showMore && (() => DetailComponent({ info: 'Here are some details 9!' }).render()), // Method 2 (inline function wrapper + .render()): Renders DetailComponent; its internal Row sources theme from context.
251
- showMore && Component(() => DetailComponent({ info: 'Here are some details 10!' })), // Method 3 (Component HOC wrapper): Renders DetailComponent; its internal Row sources theme from context.
407
+ // 7. Conditional rendering of a component returning a Node instance using an inline function wrapper.
408
+ // Renders successfully when `showMore` is true. The internal Row receives theme context.
409
+ showMore && (() => DetailComponent({ info: 'Detail 7 (Conditional inline function + Node instance)' })),
252
410
 
253
- showMore && (() => ReturnRenderedDetailComponent({ info: 'Here are some details 12!' })), // Method 4 (inline function wrapper): Renders ReturnRenderedDetailComponent; internal Row inherits theme from Column's context.
254
- showMore && Component(() => ReturnRenderedDetailComponent({ info: 'Here are some details 13!' })), // Method 5 (Component HOC wrapper): Renders ReturnRenderedDetailComponent; internal Row inherits theme from Column's context.
255
- showMore && Node(ReturnRenderedDetailComponent, { info: 'Here are some details 14!' }).render(), // Method 6 (Node HOC + .render()): Renders. Theme from Column is NOT propagated by Node HOC to internal Row.
411
+ // 8. Conditional rendering of a component returning a Node instance using an inline function wrapper, then calling .render().
412
+ // Renders successfully when `showMore` is true. The internal Row receives theme context.
413
+ showMore && (() => DetailComponent({ info: 'Detail 8 (Conditional inline function + Node instance + .render())' }).render()),
414
+
415
+ // 9. Conditional rendering of a component returning a Node instance using the Component HOC wrapper.
416
+ // Renders successfully when `showMore` is true. The internal Row receives theme context.
417
+ showMore && Component(() => DetailComponent({ info: 'Detail 9 (Conditional Component HOC + Node instance)' })),
418
+
419
+ // 10. Conditional rendering of a component returning ReactNode using an inline function wrapper.
420
+ // Renders successfully when `showMore` is true. The internal Row receives theme context.
421
+ showMore && (() => ReturnRenderedDetailComponent({ info: 'Detail 10 (Conditional inline function + ReactNode)' })),
422
+
423
+ // 11. Conditional rendering of a component returning ReactNode using the Component HOC wrapper.
424
+ // Renders successfully when `showMore` is true. The internal Row receives theme context.
425
+ showMore && Component(() => ReturnRenderedDetailComponent({ info: 'Detail 11 (Conditional Component HOC + ReactNode)' })),
256
426
  // showMore && ReturnRenderedDetailComponent({ info: 'Here are some details 15!' }), // ❌ Fails: Direct call to a component function using hooks (ReturnRenderedDetailComponent) inside render logic without a React-aware wrapper. This can violate Rules of Hooks.
257
427
  ],
258
428
  })
@@ -261,15 +431,17 @@ export default Component(() => {
261
431
  /**
262
432
  * A component that displays a styled detail section.
263
433
  * It uses `useEffect` for lifecycle logging. The internal `Row` component
264
- * sources its theme from the React context established by an ancestor
265
- * @meonode/ui component (e.g., the main Column in this page).
266
- * This component returns a @meonode/ui `Row` Node instance.
434
+ * sources its theme from the React context provided by an ancestor `@meonode/ui`
435
+ * component (like the main `Column` in this page).
267
436
  *
437
+ * This component returns a @meonode/ui `Row` Node instance.
438
+ * This type of component is suitable for direct inclusion as a child within other
439
+ * `@meonode/ui` components that expect `Node` instances or arrays of `Node` instances.
268
440
  * @param {object} props - Component properties.
269
441
  * @param {string} props.info - Text content to display in the detail section.
270
- * @returns {import('@meonode/ui').Node} A @meonode/ui Row Node instance.
442
+ * @returns {NodeInstance} A @meonode/ui Row Node instance.
271
443
  */
272
- const DetailComponent = ({ info }: { info: string }) => {
444
+ const DetailComponent = ({ info }: { info: string }): NodeInstance => {
273
445
  // useEffect hook for logging component mount and unmount phases (for debugging).
274
446
  useEffect(() => {
275
447
  console.log('DetailComponent mounted:', info) // Example mount log
@@ -278,31 +450,34 @@ const DetailComponent = ({ info }: { info: string }) => {
278
450
  }
279
451
  }, [info]) // Effect depends on 'info' prop.
280
452
 
281
- // Returns a @meonode/ui Row component configured with props and children.
453
+ // Returns a @meonode/ui Row Node instance configured with props and children.
282
454
  // Its styling (e.g., backgroundColor) will resolve theme strings from React context.
283
455
  return Row({
456
+ alignItems: 'center',
284
457
  gap: 10,
285
458
  padding: 4,
286
- border: '1px solid green',
459
+ border: '2px solid theme.accent',
287
460
  borderRadius: 6,
288
- color: 'red',
289
- backgroundColor: 'theme.background.secondary', // Background color sourced from theme in React context.
290
- children: [P(info), TextField({ background: 'theme.background.primary' })],
461
+ backgroundColor: 'theme.warning', // Background color sourced from theme in React context.
462
+ color: 'theme.danger',
463
+ children: [P(info, { flex: 1, padding: '0 20px' }), TextField({ flex: 1, sx: { background: 'theme.primary' } })],
291
464
  })
292
465
  }
293
466
 
294
467
  /**
295
468
  * An alternative detail component implementation that explicitly calls `.render()`
296
469
  * to return a `ReactNode` (a rendered React element) directly.
297
- * This makes it compatible with wrappers like the `Node` HOC that expect a function returning `ReactNode`.
470
+ * This makes it compatible with standard React rendering patterns and wrappers
471
+ * like the `Node` HOC that specifically expect a function returning `ReactNode`.
298
472
  * It uses `useEffect` for lifecycle logging. The internal `Row` sources its
299
473
  * theme from React context.
300
474
  *
475
+ * This component returns a `ReactNode`.
301
476
  * @param {object} props - Component properties.
302
477
  * @param {string} props.info - Text content to display.
303
478
  * @returns {React.ReactNode} A rendered React element (the result of `Row(...).render()`).
304
479
  */
305
- const ReturnRenderedDetailComponent = ({ info }: { info: string }) => {
480
+ const ReturnRenderedDetailComponent = ({ info }: { info: string }): ReactNode => {
306
481
  // useEffect hook for logging component mount and unmount phases (for debugging).
307
482
  useEffect(() => {
308
483
  console.log('ReturnRenderedDetailComponent mounted:', info) // Example mount log
@@ -315,52 +490,18 @@ const ReturnRenderedDetailComponent = ({ info }: { info: string }) => {
315
490
  // The Row itself will attempt to resolve theme strings (e.g., 'theme.background.secondary')
316
491
  // from the React context provided by an ancestor @meonode/ui component (like the main Column).
317
492
  return Row({
493
+ alignItems: 'center',
318
494
  gap: 10,
319
495
  padding: 4,
320
- border: '1px solid green',
496
+ border: '2px solid theme.accent',
321
497
  borderRadius: 6,
322
- color: 'red',
323
- backgroundColor: 'theme.background.secondary', // Theme-aware background; relies on theme from React context.
324
- children: [P(info), TextField({ background: 'theme.background.primary' })],
498
+ backgroundColor: 'theme.warning', // Theme-aware background; relies on theme from React context.
499
+ color: 'theme.danger',
500
+ children: [P(info, { flex: 1, padding: '0 20px' }), TextField({ flex: 1, sx: { background: 'theme.primary' } })],
325
501
  }).render() // Explicitly renders to ReactNode.
326
502
  }
327
503
  ```
328
504
 
329
- ### Material UI Integration
330
-
331
- ```shell
332
- yarn add @meonode/mui @mui/material
333
- ```
334
-
335
- ```ts
336
- import { Button, TextField } from '@meonode/mui';
337
-
338
- const MuiLoginForm = Component(() =>
339
- Div({
340
- maxWidth: '400px',
341
- margin: '0 auto',
342
- children: [
343
- TextField({
344
- label: 'Email',
345
- fullWidth: true,
346
- margin: 'normal'
347
- }),
348
- TextField({
349
- label: 'Password',
350
- type: 'password',
351
- fullWidth: true,
352
- margin: 'normal'
353
- }),
354
- Button({
355
- variant: 'contained',
356
- color: 'primary',
357
- children: 'Sign In'
358
- })
359
- ]
360
- })
361
- );
362
- ```
363
-
364
505
  ## API Reference
365
506
 
366
507
  ### Core Functions
@@ -1,12 +1,12 @@
1
1
  import React, { type ReactNode } from 'react';
2
- import type { BaseNodeInstance, ComponentNode, NodeElement, NodeProps, Theme } from './node.type.js';
2
+ import type { ComponentNode, NodeElement, NodeInstance, NodeProps, Theme } from './node.type.js';
3
3
  /**
4
4
  * Factory function to create a BaseNode instance.
5
5
  * @param element The React element type.
6
6
  * @param props The props for the node.
7
- * @returns BaseNodeInstance<E> - A new BaseNode instance.
7
+ * @returns NodeInstance<E> - A new BaseNode instance.
8
8
  */
9
- export declare function Node<E extends NodeElement>(element: E, props?: Partial<NodeProps<E>>): BaseNodeInstance<E>;
9
+ export declare function Node<E extends NodeElement>(element: E, props?: Partial<NodeProps<E>>): NodeInstance<E>;
10
10
  /**
11
11
  * Higher-order component wrapper that converts BaseNode components into React components.
12
12
  * This wrapper ensures proper theme propagation and component rendering in the React ecosystem.
@@ -31,5 +31,5 @@ export declare function Node<E extends NodeElement>(element: E, props?: Partial<
31
31
  */
32
32
  export declare function Component<T extends Record<string, any> & {
33
33
  theme?: Theme;
34
- }>(component: (props: T) => ComponentNode): (props?: T) => string | number | bigint | boolean | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | BaseNodeInstance<any> | (() => BaseNodeInstance<any> | ReactNode) | null | undefined;
34
+ }>(component: (props: T) => ComponentNode): (props?: any) => string | number | bigint | boolean | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | NodeInstance<any> | (() => NodeInstance<any> | ReactNode) | null | undefined;
35
35
  //# sourceMappingURL=core.node.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"core.node.d.ts","sourceRoot":"","sources":["../src/core.node.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAsG,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AACjJ,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAyC,WAAW,EAAE,SAAS,EAAgB,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAyX5J;;;;;GAKG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,WAAW,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,GAAE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAM,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAU9G;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG;IAAE,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,EAAE,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,aAAa,IAEzG,QAAO,CAAW,8ZAmB3B"}
1
+ {"version":3,"file":"core.node.d.ts","sourceRoot":"","sources":["../src/core.node.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAkF,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAC7H,OAAO,KAAK,EAAE,aAAa,EAAyC,WAAW,EAAE,YAAY,EAAE,SAAS,EAAgB,KAAK,EAAE,MAAM,mBAAmB,CAAA;AA0bxJ;;;;;GAKG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,WAAW,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,GAAE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAM,GAAG,YAAY,CAAC,CAAC,CAAC,CAU1G;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG;IAAE,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,EAAE,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,aAAa,IAEzG,QAAO,GAAQ,sZAmBxB"}
package/dist/core.node.js CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";var _excluded=["children","nodeTheme"],_excluded2=["children","key"];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 _classCallCheck(b,a){if(!(b instanceof a))throw new TypeError("Cannot call a class as a function")}function _defineProperties(a,b){for(var c,d=0;d<b.length;d++)c=b[d],c.enumerable=c.enumerable||!1,c.configurable=!0,"value"in c&&(c.writable=!0),Object.defineProperty(a,_toPropertyKey(c.key),c)}function _createClass(a,b,c){return b&&_defineProperties(a.prototype,b),c&&_defineProperties(a,c),Object.defineProperty(a,"prototype",{writable:!1}),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,{createElement,isValidElement}from"react";import{getComponentType,getCSSProps,getDOMProps,getElementTypeName,getValueByPath}from"./node.helper.js";import{isForwardRef,isMemo,isReactClassComponent,isValidElementType}from"./react-is.helper.js";/**
1
+ "use strict";var _excluded=["children","nodeTheme","theme"],_excluded2=["children","key"];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 _classCallCheck(b,a){if(!(b instanceof a))throw new TypeError("Cannot call a class as a function")}function _defineProperties(a,b){for(var c,d=0;d<b.length;d++)c=b[d],c.enumerable=c.enumerable||!1,c.configurable=!0,"value"in c&&(c.writable=!0),Object.defineProperty(a,_toPropertyKey(c.key),c)}function _createClass(a,b,c){return b&&_defineProperties(a.prototype,b),c&&_defineProperties(a,c),Object.defineProperty(a,"prototype",{writable:!1}),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,{createElement,isValidElement}from"react";import{getComponentType,getCSSProps,getDOMProps,getElementTypeName,getValueByPath}from"./node.helper.js";import{isForwardRef,isMemo,isReactClassComponent,isValidElementType}from"./react-is.helper.js";import{createRoot}from"react-dom/client";/**
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
@@ -6,7 +6,7 @@
6
6
  * - Child node processing and management
7
7
  * - Style processing with theme variables
8
8
  * @template E The type of React element or component this node represents
9
- */var BaseNode=/*#__PURE__*/function(){/** The underlying React element or component type that this node represents *//** Original props passed during construction, preserved for cloning/recreation *//** Processed props after theme resolution, style processing, and child normalization *//**
9
+ */var BaseNode=/*#__PURE__*/function(){/**
10
10
  * Creates a new BaseNode instance that wraps a React element.
11
11
  * Processes raw props by:
12
12
  * - Extracting and resolving theme-aware styles
@@ -14,28 +14,34 @@
14
14
  * - Normalizing children with theme inheritance
15
15
  * @param element The React element/component to wrap
16
16
  * @param rawProps Initial props including theme, styles, and children
17
- */function BaseNode(a,b){var c=this;_classCallCheck(this,BaseNode),_defineProperty(this,"_normalizeChild",function(a){var b,d;if(!a)return a;var e=(null===(b=c.rawProps)||void 0===b?void 0:b.nodeTheme)||(null===(d=c.rawProps)||void 0===d?void 0:d.theme)||c.props.nodeTheme||c.props.theme;// For BaseNode instances, apply current theme if child has no theme
17
+ */function BaseNode(a){var b=this,c=1<arguments.length&&arguments[1]!==void 0?arguments[1]:{};_classCallCheck(this,BaseNode),_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
18
18
  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()}// For React.Component instances, wrap in BaseNode with theme if needed
19
19
  if(a instanceof React.Component)return a.props.nodeTheme||void 0===e?a.render():new BaseNode(a.render(),_objectSpread(_objectSpread({},a.props),{},{nodeTheme:e})).render();// Validate element type before returning
20
20
  if(!isValidElementType(a)){var g=getComponentType(a);throw new Error("Invalid element type: ".concat(g," provided!"))}// Return valid React elements as-is
21
- return a}),this.element=a,this.rawProps=b;var d=b||{},e=d.children,f=d.nodeTheme,g=_objectWithoutProperties(d,_excluded),h=getCSSProps(g),i=this._resolveStyleWithTheme(h,f);// Process styles with theme variables
22
- i=0<Object.keys(i).length?i:{};// Extract non-style DOM props
23
- var j=getDOMProps(g),k=void 0;// Process children with theme inheritance
24
- if(e!==void 0&&null!==e)if(Array.isArray(e)){k=e.map(function(a,b){return c._processRawNode(a,f,b)})}else k=this._processRawNode(e,f);// Build final normalized props
25
- this.props=_objectSpread(_objectSpread({},j),{},{style:i,nodeTheme:f,children:k})}/**
26
- * Resolves style properties by replacing theme path placeholders with actual theme values.
27
- * Handles complex strings like '1px solid theme.background.primary' and iterative resolution.
28
- * @param initialCssProps The initial CSS properties object.
21
+ return a}),this.element=a,this.rawProps=c;// Destructure raw props into relevant parts
22
+ var d=c.children,e=c.nodeTheme,f=c.theme,g=_objectWithoutProperties(c,_excluded),h=this._resolveObjWithTheme(g,e),i=getCSSProps(h),j=getDOMProps(h),k=void 0;// Resolve any theme variables in the remaining props
23
+ // Extract style-related props that match valid CSS properties
24
+ // Extract remaining props that are valid DOM attributes
25
+ // Process children while maintaining theme inheritance
26
+ // Combine processed props into final normalized form
27
+ d&&(Array.isArray(d)?k=d.map(function(a,c){return b._processRawNode(a,e,c)}):k=this._processRawNode(d,e)),this.props=_objectSpread(_objectSpread({},j),{},{style:i,nodeTheme:e,children:k})}/**
28
+ * Resolves obj properties by replacing theme path placeholders with actual theme values.
29
+ * Handles complex strings like '1px solid theme.background.primary' and nested objects.
30
+ * @param obj The initial obj properties object.
29
31
  * @param theme The theme object to use for resolving paths.
30
32
  * @returns A new CSSProperties object with theme values resolved.
31
- */return _createClass(BaseNode,[{key:"_resolveStyleWithTheme",value:function _resolveStyleWithTheme(a,b){var c;// If no theme is provided or there are no initial CSS props to process, return the initial props.
32
- if(!b||0===Object.keys(a).length)return a;var d=_objectSpread(_objectSpread({},null===(c=this.rawProps)||void 0===c?void 0:c.nodeTheme),b),e=_objectSpread({},a);// Merge nodeTheme from rawProps with theme
33
- for(var f in e)if(Object.prototype.hasOwnProperty.call(e,f)){var g=e[f];if("string"==typeof g&&g.includes("theme.")){var h=g;// Iteratively resolve theme references within the string
34
- h=h.replace(/theme\.([a-zA-Z0-9_.-]+)/g,function(a,b){var c=getValueByPath(d,b);// Use 'theme' passed to the function
35
- // Replace it if themeValue is found and is a string or number.
36
- // null is explicitly excluded to avoid 'null' string in output unless intended.
37
- return void 0!==c&&null!==c&&("string"==typeof c||"number"==typeof c)?c+"":a;// If themeValue is not a string or number or is undefined/null, keep the original placeholder
38
- }),e[f]=h}}return e}/**
33
+ */return _createClass(BaseNode,[{key:"_resolveObjWithTheme",value:function _resolveObjWithTheme(a,b){var c;// Return early if no theme or empty object
34
+ if(!b||0===Object.keys(a).length)return a;// Merge raw nodeTheme with passed theme for resolution
35
+ var d=_objectSpread(_objectSpread({},null===(c=this.rawProps)||void 0===c?void 0:c.nodeTheme),b),e=function resolveRecursively(a){var b={};// Process each property in the current object
36
+ for(var c in a){var f=a[c];if(c.startsWith("_"))return a;// Handle string values containing theme references
37
+ if("string"==typeof f&&f.includes("theme.")){var g=f;// Replace theme path placeholders with actual theme values
38
+ g=g.replace(/theme\.([a-zA-Z0-9_.-]+)/g,function(a,b){var c=getValueByPath(d,b);// Convert the theme value to string if it exists and is a valid type
39
+ return null!=c&&["string","number"].includes(_typeof(c))?c+"":a}),b[c]=g}// Recursively process nested objects (excluding arrays)
40
+ else b[c]=f&&"object"===_typeof(f)?e(f):f}return b};/**
41
+ * Recursively resolves theme values in an object
42
+ * @param currentObj The current object level being processed
43
+ * @returns New object with resolved theme values
44
+ */return e(a)}/**
39
45
  * React component that renders the result of a function child, supporting theme propagation.
40
46
  *
41
47
  * This component is used to render children that are functions (i.e., `() => Children`).
@@ -48,11 +54,9 @@ return void 0!==c&&null!==c&&("string"==typeof c||"number"==typeof c)?c+"":a;//
48
54
  */},{key:"_functionRenderer",value:function _functionRenderer(a){var b=a.render,c=a.passedTheme,d=a.passedKey,e=a.processRawNode,f=b();// Call the user-provided render function to get the child.
49
55
  if(f instanceof React.Component){var g=f.render(),h=e(g,c);return h instanceof BaseNode?h.render():h}if(f instanceof BaseNode){var i,j=f;// If the returned BaseNode does not have its own theme, but a theme is provided,
50
56
  // re-create the node with the provided theme to ensure correct theme propagation.
51
- return void 0===(null===(i=j.rawProps)||void 0===i?void 0:i.nodeTheme)&&void 0!==c?new BaseNode(j.element,_objectSpread(_objectSpread({},j.rawProps||{}),{},{nodeTheme:c,theme:c,// Pass theme for consistency if used in rawProps
52
- key:d})).render():j.render();// If the node already has a theme or no theme is provided, render as-is.
57
+ return void 0===(null===(i=j.rawProps)||void 0===i?void 0:i.nodeTheme)&&void 0!==c?new BaseNode(j.element,_objectSpread(_objectSpread({},j.rawProps||{}),{},{nodeTheme:c,theme:c,key:d})).render():j.render();// If the node already has a theme or no theme is provided, render as-is.
53
58
  }// Process the result if it's not a React.Component or BaseNode
54
- var k=e(f,c);if(k instanceof BaseNode){var l,m;if(((null===(l=k.rawProps)||void 0===l?void 0:l.theme)||(null===(m=k.rawProps)||void 0===m?void 0:m.nodeTheme))===void 0&&c!==void 0){var n,o,p;return new BaseNode(k.element,_objectSpread(_objectSpread({},k.rawProps),{},{nodeTheme:(null===(n=k.rawProps)||void 0===n?void 0:n.theme)||(null===(o=k.rawProps)||void 0===o?void 0:o.nodeTheme)||c,key:(null===(p=k.rawProps)||void 0===p?void 0:p.key)||d// Use an existing key or passed key
55
- })).render()}return k.render()}// If the result is not a BaseNode (e.g., JSX, string, etc.), return it directly.
59
+ var k=e(f,c);if(k instanceof BaseNode){var l,m;if(((null===(l=k.rawProps)||void 0===l?void 0:l.theme)||(null===(m=k.rawProps)||void 0===m?void 0:m.nodeTheme))===void 0&&c!==void 0){var n,o,p;return new BaseNode(k.element,_objectSpread(_objectSpread({},k.rawProps),{},{nodeTheme:(null===(n=k.rawProps)||void 0===n?void 0:n.theme)||(null===(o=k.rawProps)||void 0===o?void 0:o.nodeTheme)||c,key:(null===(p=k.rawProps)||void 0===p?void 0:p.key)||d})).render()}return k.render()}// If the result is not a BaseNode (e.g., JSX, string, etc.), return it directly.
56
60
  // Note: Non-BaseNode results will not automatically receive the theme.
57
61
  return f}/**
58
62
  * Processes a single raw child element, converting it into a ProcessedChild.
@@ -119,11 +123,11 @@ var h=_objectSpread(_objectSpread({},e),{},{// Cast otherProps
119
123
  key:d// This is the key of the current BaseNode itself
120
124
  });// Prepare props for React.createElement
121
125
  // Delete the key `nodeTheme` as it's not a valid DOM/React prop for the element
122
- return delete h.nodeTheme,createElement(this.element,h,f)}}])}();/**
126
+ return delete h.nodeTheme,createElement(this.element,h,f)}},{key:"_ensurePortalInfrastructure",value:function _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}},{key:"toPortal",value:function 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)}})}}])}();/**
123
127
  * Factory function to create a BaseNode instance.
124
128
  * @param element The React element type.
125
129
  * @param props The props for the node.
126
- * @returns BaseNodeInstance<E> - A new BaseNode instance.
130
+ * @returns NodeInstance<E> - A new BaseNode instance.
127
131
  */export function Node(a){var b=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{},c=_objectSpread({},b);// Ensure we are working with a mutable copy
128
132
  // 'theme' prop itself is not directly used by BaseNode after this, nodeTheme is used.
129
133
  // We can keep `theme` in rawProps if needed for cloning or inspection.
@@ -149,7 +153,7 @@ return c.theme&&void 0===c.nodeTheme&&(c.nodeTheme=c.theme),new BaseNode(a,c)}/*
149
153
  * })
150
154
  * ```
151
155
  */export function Component(a){// Create a wrapper component that handles theme and rendering
152
- return function(){var b=0<arguments.length&&arguments[0]!==void 0?arguments[0]:{},c=a(_objectSpread({},b));// Execute wrapped component
156
+ return function(){var b=0<arguments.length&&arguments[0]!==void 0?arguments[0]:{},c=a(b);// Execute wrapped component
153
157
  // Handle BaseNode results - requires special processing
154
158
  if(c instanceof BaseNode){var d,e;// Theme merging: Check if we need to handle theme inheritance
155
159
  if(!!(null!==b&&void 0!==b&&b.theme||null!==b&&void 0!==b&&b.nodeTheme)||!!(null!==(d=c.rawProps)&&void 0!==d&&d.theme||null!==(e=c.rawProps)&&void 0!==e&&e.nodeTheme)){var f,g;return new BaseNode(c.element,_objectSpread(_objectSpread({},c.rawProps),{},{// Theme priority: props.theme > rawProps.theme > rawProps.nodeTheme