@meonode/ui 0.1.9 → 0.1.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/README.md CHANGED
@@ -163,40 +163,53 @@ const Dashboard = Component(() =>
163
163
 
164
164
  ### With Conditional Children That Contains Hook
165
165
 
166
- also add this
167
-
168
166
  ```ts
169
-
170
167
  // Wraps a hook-capable component into a BaseNode-compatible Client Component
171
- import { Component, Column, Row, Div, P } from '@meonode/ui'
168
+ 'use client'
169
+ /**
170
+ * This file demonstrates integration between React hooks and BaseNode components
171
+ * using the @meonode/ui library for declarative UI construction
172
+ */
173
+ import { Component, Column, Row, Div, P, Node } from '@meonode/ui'
172
174
  import { useState, useEffect } from 'react'
173
175
 
174
- // Shared theme object passed into components. This may be written in a different file and imported.
176
+ /**
177
+ * Global theme configuration
178
+ * Contains color palette definitions used throughout components
179
+ * Can be extracted to separate theme file if needed
180
+ */
175
181
  const theme = {
176
182
  background: { primary: 'lightgreen', secondary: 'lightyellow' },
177
183
  }
178
184
 
179
- // Exported component rendered via <Component /> (client wrapper)
185
+ /**
186
+ * Main page component wrapped in Component HOC to enable client-side features
187
+ * Demonstrates conditional rendering and component composition patterns
188
+ */
180
189
  export default Component(() => {
181
- // React hook for conditional UI
190
+ // Controls visibility of detail sections
182
191
  const [showDetails, setShowDetails] = useState(false)
183
192
 
184
- // Declarative layout using Column as root container
193
+ /**
194
+ * Main layout structured as a Column with:
195
+ * - Header row containing toggle button
196
+ * - Conditional detail sections using different rendering approaches
197
+ */
185
198
  return Column({
186
199
  theme,
187
200
  padding: 20,
188
201
  gap: 15,
189
202
  children: [
190
- // Header row with a toggle button
203
+ // Interactive header section
191
204
  Row({
192
205
  gap: 10,
193
206
  children: [
194
207
  Div({
195
- onClick: () => setShowDetails(prev => !prev),
208
+ onClick: () => setShowDetails(prev => !prev), // Toggle detail visibility
196
209
  cursor: 'pointer',
197
- userSelect: 'none',
210
+ userSelect: 'none', // Prevent text selection
198
211
  padding: '10px 20px',
199
- backgroundColor: 'theme.background.primary', // Node engine will handle this
212
+ backgroundColor: 'theme.background.primary', // Themed background
200
213
  borderRadius: 5,
201
214
  fontWeight: 'bold',
202
215
  children: showDetails ? 'Hide Details' : 'Show Details',
@@ -204,17 +217,31 @@ export default Component(() => {
204
217
  ],
205
218
  }),
206
219
 
207
- // Conditionally render DetailComponent via function wrapper
208
- // Ensures it's treated as a renderable function (deferred React class or element that is NOT called directly)
209
- // Node engine will handle this like magic
210
- showDetails && (() => DetailComponent({ info: 'Here are some details!' })), // Works like `Component(() => DetailComponent({ info: 'Here some details!' }))`,
211
- showDetails && DetailComponent({ info: 'Here are some details!' }).render() // Works
220
+ /**
221
+ * Multiple approaches to conditional detail rendering:
222
+ * 1. Direct function wrapping
223
+ * 2. Component HOC wrapping
224
+ * 3. Node with ReturnRenderedDetailComponent
225
+ * 4. Non-working example with raw Node usage
226
+ */
227
+ showDetails && (() => DetailComponent({ info: 'Here are some details 1!' })), // Method 1
228
+ showDetails && Component(() => DetailComponent({ info: 'Here are some details 2!' })), // Method 2
229
+ showDetails && Node(ReturnRenderedDetailComponent, { info: 'Here are some details 2!' }).render(), // Method 3
230
+
231
+ // Fails because DetailComponent returns Node instance instead of ReactNode
232
+ showDetails && Node(DetailComponent, { info: 'Here are some details 2!' }).render(), // ❌ Invalid
212
233
  ],
213
234
  })
214
235
  })
215
236
 
216
- // A stateful detail section using useEffect and styled Div
237
+ /**
238
+ * Displays a styled detail section with lifecycle logging
239
+ * @param {Object} props - Component properties
240
+ * @param {string} props.info - Text content to display
241
+ * @returns {Node} Rendered Div Node instance
242
+ */
217
243
  const DetailComponent = ({ info }: { info: string }) => {
244
+ // Log component lifecycle for debugging
218
245
  useEffect(() => {
219
246
  console.log('DetailComponent mounted')
220
247
  return () => {
@@ -222,15 +249,44 @@ const DetailComponent = ({ info }: { info: string }) => {
222
249
  }
223
250
  }, [])
224
251
 
252
+ // Themed container with text content
225
253
  return Div({
226
254
  padding: 15,
227
255
  border: '1px solid green',
228
256
  borderRadius: 6,
229
- backgroundColor: 'theme.background.secondary', // Node engine will handle this
257
+ color: 'red',
258
+ backgroundColor: 'theme.background.secondary', // Theme-aware background
230
259
  children: P(info),
231
260
  })
232
261
  }
233
262
 
263
+ /**
264
+ * Alternative implementation that explicitly returns rendered content
265
+ * Functionally identical to DetailComponent but compatible with Node wrapper
266
+ * @param {Object} props - Component properties
267
+ * @param {string} props.info - Text content to display
268
+ * @returns {ReactNode} Rendered React element
269
+ */
270
+ const ReturnRenderedDetailComponent = ({ info }: { info: string }) => {
271
+ // Log component lifecycle for debugging
272
+ useEffect(() => {
273
+ console.log('DetailComponent mounted')
274
+ return () => {
275
+ console.log('DetailComponent unmounted')
276
+ }
277
+ }, [])
278
+
279
+ // Themed container with text content
280
+ return Div({
281
+ padding: 15,
282
+ border: '1px solid green',
283
+ borderRadius: 6,
284
+ color: 'red',
285
+ backgroundColor: 'theme.background.secondary', // Theme-aware background
286
+ children: P(info),
287
+ }).render()
288
+ }
289
+
234
290
  ```
235
291
 
236
292
  ### Material UI Integration
@@ -1,5 +1,5 @@
1
- import React, { ReactNode } from 'react';
2
- import { BaseNodeInstance, NodeElement, NodeProps } from './node.type.js';
1
+ import React, { type ReactNode } from 'react';
2
+ import type { BaseNodeInstance, NodeElement, NodeProps } from './node.type.js';
3
3
  /**
4
4
  * Factory function to create a BaseNode instance.
5
5
  * @param element The React element type.
@@ -1 +1 @@
1
- {"version":3,"file":"core.node.d.ts","sourceRoot":"","sources":["../src/core.node.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAkF,SAAS,EAAE,MAAM,OAAO,CAAA;AACxH,OAAO,EAAE,gBAAgB,EAAwC,WAAW,EAAE,SAAS,EAA4B,MAAM,mBAAmB,CAAA;AAuT5I;;;;;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,CAS9G;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,gBAAgB,CAAC,GAAG,CAAC,GAAG,SAAS,IACzG,OAAO,CAAC,kXAOjB"}
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,EAAwC,WAAW,EAAE,SAAS,EAA4B,MAAM,mBAAmB,CAAA;AAuTjJ;;;;;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,CAS9G;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,gBAAgB,CAAC,GAAG,CAAC,GAAG,SAAS,IACzG,OAAO,CAAC,kXAOjB"}
package/dist/core.node.js CHANGED
@@ -53,7 +53,7 @@ return f}/**
53
53
  ){var d=getComponentType(a),e=function generateIndexedKeyIfNeeded(a,b){if(b!==void 0&&null!==b)return b;if(void 0!==c){var d=getElementTypeName(a);return"".concat(d,"-").concat(c)}// No explicit key, and not an array child, so BaseNode constructor will handle.
54
54
  };// Helper to generate an indexed key if no explicit key is present and an index is available.
55
55
  // Case 1: Child is already a BaseNode instance
56
- if(a instanceof BaseNode||"object"===_typeof(a)&&null!==a&&!0===a._isBaseNode){var f=a,g=f.rawProps||{},h=g.nodeTheme,i=e(f.element,g.key);// Prefer child's own theme
56
+ if(a instanceof BaseNode){var f=a,g=f.rawProps||{},h=g.nodeTheme,i=e(f.element,g.key);// Prefer child's own theme
57
57
  return new BaseNode(f.element,_objectSpread(_objectSpread({},g),{},{nodeTheme:h||b||{},key:i}))}// Case 2: Child is a primitive (string, number, boolean, null, undefined)
58
58
  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).
59
59
  if("function"===d&&!isReactClassComponent(a)&&!isMemo(a)&&!isForwardRef(a)){// The key is for the BaseNode that wraps the _functionRenderer component.
@@ -104,4 +104,4 @@ return c.theme&&void 0===c.nodeTheme&&(c.nodeTheme=c.theme),new BaseNode(a,c)}/*
104
104
  * const MyComponent = Component((props) => {
105
105
  * return Node('div', { ...props })
106
106
  * })
107
- */export function Component(a){return function(b){var d=a(b);return d instanceof BaseNode||"object"===_typeof(d)&&null!==d&&!0===d._isBaseNode?d.render():d}}
107
+ */export function Component(a){return function(b){var d=a(b);return d instanceof BaseNode?d.render():d}}
@@ -1,5 +1,5 @@
1
1
  import type { Attributes as ReactAttributes, ComponentProps, CSSProperties, ReactNode, JSX, ElementType, ComponentType, JSXElementConstructor, ReactInstance } from 'react';
2
- export type NodeElement = ReactNode | ReactInstance | ElementType | ComponentType | BaseNodeInstance<any> | ((props?: any) => ReactNode | Promise<ReactNode> | ReactInstance | BaseNodeInstance<any>);
2
+ export type NodeElement = ReactNode | ReactInstance | ElementType | ComponentType<any> | BaseNodeInstance<any> | ((props?: any) => ReactNode | Promise<ReactNode> | ReactInstance | BaseNodeInstance<any>);
3
3
  /**
4
4
  * Defines valid child types that can be passed to a node:
5
5
  * - ReactNode: Any valid React child (elements, strings, numbers, etc.)
@@ -1 +1 @@
1
- {"version":3,"file":"node.type.d.ts","sourceRoot":"","sources":["../src/node.type.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"node.type.d.ts","sourceRoot":"","sources":["../src/node.type.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@meonode/ui",
3
3
  "description": "A structured approach to component composition with built-in theming, prop separation, and dynamic children handling.",
4
- "version": "0.1.9",
4
+ "version": "0.1.11",
5
5
  "type": "module",
6
6
  "main": "./dist/main.js",
7
7
  "types": "./dist/main.d.ts",