@meonode/ui 0.1.9 → 0.1.10

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
@@ -166,37 +166,52 @@ const Dashboard = Component(() =>
166
166
  also add this
167
167
 
168
168
  ```ts
169
-
170
169
  // Wraps a hook-capable component into a BaseNode-compatible Client Component
171
- import { Component, Column, Row, Div, P } from '@meonode/ui'
170
+ 'use client'
171
+ /**
172
+ * This file demonstrates integration between React hooks and BaseNode components
173
+ * using the @meonode/ui library for declarative UI construction
174
+ */
175
+ import { Component, Column, Row, Div, P, Node } from '@meonode/ui'
172
176
  import { useState, useEffect } from 'react'
173
177
 
174
- // Shared theme object passed into components. This may be written in a different file and imported.
178
+ /**
179
+ * Global theme configuration
180
+ * Contains color palette definitions used throughout components
181
+ * Can be extracted to separate theme file if needed
182
+ */
175
183
  const theme = {
176
184
  background: { primary: 'lightgreen', secondary: 'lightyellow' },
177
185
  }
178
186
 
179
- // Exported component rendered via <Component /> (client wrapper)
187
+ /**
188
+ * Main page component wrapped in Component HOC to enable client-side features
189
+ * Demonstrates conditional rendering and component composition patterns
190
+ */
180
191
  export default Component(() => {
181
- // React hook for conditional UI
192
+ // Controls visibility of detail sections
182
193
  const [showDetails, setShowDetails] = useState(false)
183
194
 
184
- // Declarative layout using Column as root container
195
+ /**
196
+ * Main layout structured as a Column with:
197
+ * - Header row containing toggle button
198
+ * - Conditional detail sections using different rendering approaches
199
+ */
185
200
  return Column({
186
201
  theme,
187
202
  padding: 20,
188
203
  gap: 15,
189
204
  children: [
190
- // Header row with a toggle button
205
+ // Interactive header section
191
206
  Row({
192
207
  gap: 10,
193
208
  children: [
194
209
  Div({
195
- onClick: () => setShowDetails(prev => !prev),
210
+ onClick: () => setShowDetails(prev => !prev), // Toggle detail visibility
196
211
  cursor: 'pointer',
197
- userSelect: 'none',
212
+ userSelect: 'none', // Prevent text selection
198
213
  padding: '10px 20px',
199
- backgroundColor: 'theme.background.primary', // Node engine will handle this
214
+ backgroundColor: 'theme.background.primary', // Themed background
200
215
  borderRadius: 5,
201
216
  fontWeight: 'bold',
202
217
  children: showDetails ? 'Hide Details' : 'Show Details',
@@ -204,17 +219,31 @@ export default Component(() => {
204
219
  ],
205
220
  }),
206
221
 
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
222
+ /**
223
+ * Multiple approaches to conditional detail rendering:
224
+ * 1. Direct function wrapping
225
+ * 2. Component HOC wrapping
226
+ * 3. Node with ReturnRenderedDetailComponent
227
+ * 4. Non-working example with raw Node usage
228
+ */
229
+ showDetails && (() => DetailComponent({ info: 'Here are some details 1!' })), // Method 1
230
+ showDetails && Component(() => DetailComponent({ info: 'Here are some details 2!' })), // Method 2
231
+ showDetails && Node(ReturnRenderedDetailComponent, { info: 'Here are some details 2!' }).render(), // Method 3
232
+
233
+ // Fails because DetailComponent returns Node instance instead of ReactNode
234
+ showDetails && Node(DetailComponent, { info: 'Here are some details 2!' }).render(), // ❌ Invalid
212
235
  ],
213
236
  })
214
237
  })
215
238
 
216
- // A stateful detail section using useEffect and styled Div
239
+ /**
240
+ * Displays a styled detail section with lifecycle logging
241
+ * @param {Object} props - Component properties
242
+ * @param {string} props.info - Text content to display
243
+ * @returns {Node} Rendered Div Node instance
244
+ */
217
245
  const DetailComponent = ({ info }: { info: string }) => {
246
+ // Log component lifecycle for debugging
218
247
  useEffect(() => {
219
248
  console.log('DetailComponent mounted')
220
249
  return () => {
@@ -222,15 +251,44 @@ const DetailComponent = ({ info }: { info: string }) => {
222
251
  }
223
252
  }, [])
224
253
 
254
+ // Themed container with text content
225
255
  return Div({
226
256
  padding: 15,
227
257
  border: '1px solid green',
228
258
  borderRadius: 6,
229
- backgroundColor: 'theme.background.secondary', // Node engine will handle this
259
+ color: 'red',
260
+ backgroundColor: 'theme.background.secondary', // Theme-aware background
230
261
  children: P(info),
231
262
  })
232
263
  }
233
264
 
265
+ /**
266
+ * Alternative implementation that explicitly returns rendered content
267
+ * Functionally identical to DetailComponent but compatible with Node wrapper
268
+ * @param {Object} props - Component properties
269
+ * @param {string} props.info - Text content to display
270
+ * @returns {ReactNode} Rendered React element
271
+ */
272
+ const ReturnRenderedDetailComponent = ({ info }: { info: string }) => {
273
+ // Log component lifecycle for debugging
274
+ useEffect(() => {
275
+ console.log('DetailComponent mounted')
276
+ return () => {
277
+ console.log('DetailComponent unmounted')
278
+ }
279
+ }, [])
280
+
281
+ // Themed container with text content
282
+ return Div({
283
+ padding: 15,
284
+ border: '1px solid green',
285
+ borderRadius: 6,
286
+ color: 'red',
287
+ backgroundColor: 'theme.background.secondary', // Theme-aware background
288
+ children: P(info),
289
+ }).render()
290
+ }
291
+
234
292
  ```
235
293
 
236
294
  ### 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.10",
5
5
  "type": "module",
6
6
  "main": "./dist/main.js",
7
7
  "types": "./dist/main.d.ts",