@meonode/ui 0.1.19 → 0.1.20

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.
Files changed (2) hide show
  1. package/README.md +146 -62
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,25 +1,30 @@
1
+ [file name]: README.md
2
+ [file content begin]
1
3
  # @meonode/ui
2
4
 
3
5
  [![NPM version](https://img.shields.io/npm/v/@meonode/ui.svg?style=flat)](https://www.npmjs.com/package/@meonode/ui)
4
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+ [![Bundle Size](https://img.shields.io/bundlephobia/minzip/@meonode/ui)](https://bundlephobia.com/package/@meonode/ui)
5
8
 
6
9
  **Build React UIs with Type-Safe Fluency**
7
10
  A structured approach to component composition with built-in theming, prop separation, and dynamic children handling.
8
11
 
9
- ```ts
12
+ ```tsx
10
13
  // Quick Start Example
11
14
  import { Component, Div, H1, Button } from '@meonode/ui';
12
15
 
16
+ // Create a reusable styled component
13
17
  const BlueButton = Component((props) =>
14
18
  Button('Blue', {
15
19
  padding: '12px 24px',
16
20
  borderRadius: '8px',
17
21
  backgroundColor: 'dodgerblue',
18
22
  color: 'white',
19
- ...props
23
+ ...props // Merge with incoming props
20
24
  })
21
25
  );
22
26
 
27
+ // Compose your app
23
28
  const App = Component(() =>
24
29
  Div({
25
30
  padding: '40px',
@@ -36,37 +41,45 @@ const App = Component(() =>
36
41
 
37
42
  ## Why @meonode/ui?
38
43
 
39
- - 🎯 **Type-Safe Design** - Full TypeScript support with autocomplete for styles and themes
40
- - 🎨 **CSS-in-JS Without Runtime** - Write styles directly in props with theme references
44
+ - 🎯 **Type-Safe Design** - Full TypeScript support with autocomplete for styles, props, and theme paths
45
+ - 🎨 **Theme-Aware Styles** - Write styles directly in props with dynamic theme resolution
41
46
  - 🧩 **Component-First Architecture** - Compose UIs from structured nodes instead of JSX
42
- - 🌐 **Theme Propagation** - Contextual theming that works with any component structure
43
- - ⚡ **Zero Dependencies** - Lightweight core (under 15kb gzipped)
47
+ - 🌐 **Contextual Theming** - Theme values propagate automatically through nested components
48
+ - ⚡ **Optimized Bundle** - Efficient core with tree-shaking support
49
+ - 🔄 **Seamless React Integration** - Works with hooks, HOCs, and React 18+ features
44
50
 
45
51
  ## Installation
46
52
 
47
- ```shell
53
+ ```bash
54
+ # Using npm
48
55
  npm install @meonode/ui react
49
- # or
56
+
57
+ # Using yarn
50
58
  yarn add @meonode/ui react
59
+
60
+ # Using pnpm
61
+ pnpm add @meonode/ui react
51
62
  ```
52
63
 
64
+ ---
65
+
53
66
  ## Core Concepts
54
67
 
55
68
  ### 1. Component Creation
56
69
 
57
- Create elements using the `Node` factory or pre-built components:
70
+ Create elements using either the `Node` factory or pre-built components:
58
71
 
59
- ```ts
72
+ ```tsx
60
73
  import { Node, Div, H1 } from '@meonode/ui';
61
74
 
62
- // Using Node factory
75
+ // Method 1: Node factory for custom elements
63
76
  const Card = Node('div', {
64
77
  padding: '20px',
65
78
  borderRadius: '8px',
66
79
  boxShadow: '0 2px 12px rgba(0,0,0,0.1)'
67
80
  });
68
81
 
69
- // Using pre-built components
82
+ // Method 2: Pre-built semantic components
70
83
  const Header = () =>
71
84
  Div({
72
85
  padding: '20px',
@@ -77,10 +90,11 @@ const Header = () =>
77
90
 
78
91
  ### 2. Theming System
79
92
 
80
- Define and consume themes with dot-notation:
93
+ Define themes and access values using dot-notation:
81
94
 
82
- ```ts
83
- const theme = {
95
+ ```tsx
96
+ // theme.ts
97
+ export const theme = {
84
98
  colors: {
85
99
  primary: '#2196F3',
86
100
  text: {
@@ -94,9 +108,13 @@ const theme = {
94
108
  }
95
109
  };
96
110
 
111
+ // ThemedComponent.tsx
112
+ import { Component, Div, H1, P } from '@meonode/ui';
113
+ import { theme } from './theme';
114
+
97
115
  const ThemedCard = Component(() =>
98
116
  Div({
99
- theme,
117
+ theme, // Provide theme context
100
118
  padding: 'theme.spacing.lg',
101
119
  backgroundColor: 'theme.colors.primary',
102
120
  children: [
@@ -111,47 +129,49 @@ const ThemedCard = Component(() =>
111
129
 
112
130
  Automatic separation of CSS props from DOM attributes:
113
131
 
114
- ```ts
132
+ ```tsx
115
133
  const ProfileCard = Component(({ user }) =>
116
134
  Div({
117
135
  // CSS Props
118
136
  padding: '20px',
119
137
  borderRadius: '8px',
138
+
120
139
  // DOM Props
121
- ariaRole: 'article',
140
+ 'aria-role': 'article',
122
141
  tabIndex: 0,
142
+
123
143
  // Children
124
144
  children: `Welcome ${user.name}!`
125
145
  })
126
146
  );
127
147
  ```
128
148
 
149
+ ---
129
150
 
130
151
  ## Key Features
131
152
 
132
- | Feature | Description |
133
- |----------------------|----------------------------------------------------------------------|
134
- | **Smart Prop Merge** | CSS properties are automatically merged with style object |
135
- | **Theme Resolution** | `theme.` references resolve through component hierarchy |
136
- | **Type Safety** | Autocomplete for CSS properties and theme paths |
137
- | **HOC Support** | Wrap existing components with `Component()` for seamless integration |
138
- | **Dynamic Children** | Function-as-child pattern with automatic theme propagation |
153
+ | Feature | Description |
154
+ |----------------------|-----------------------------------------------------------------------------|
155
+ | **Smart Prop Merge** | CSS props merge with style objects; DOM props pass to underlying elements |
156
+ | **Theme Resolution** | `theme.` references resolve through component hierarchy |
157
+ | **Type Guards** | Autocomplete for CSS properties and theme paths with strict type checks |
158
+ | **HOC Support** | Wrap existing components with `Component()` for theme integration |
159
+ | **Dynamic Children** | Supports function-as-child pattern with automatic theme propagation |
160
+
161
+ ---
139
162
 
140
- ## Advanced Usage
163
+ ## Advanced Patterns
141
164
 
142
165
  ### Component Composition
143
166
 
144
- ```ts
167
+ ```tsx
145
168
  const Dashboard = Component(() =>
146
169
  Div({
147
170
  display: 'grid',
148
171
  gridTemplateColumns: '1fr 3fr',
149
172
  gap: '20px',
150
173
  children: [
151
- Sidebar({
152
- width: '240px',
153
- items: navItems
154
- }),
174
+ Sidebar({ width: '240px' }),
155
175
  MainContent({
156
176
  padding: '40px',
157
177
  children: AnalyticsChart({ dataset })
@@ -163,32 +183,22 @@ const Dashboard = Component(() =>
163
183
 
164
184
  ### Material UI Integration
165
185
 
166
- ```shell
186
+ ```bash
167
187
  yarn add @meonode/mui @mui/material
168
188
  ```
169
189
 
170
- ```ts
190
+ ```tsx
171
191
  import { Button, TextField } from '@meonode/mui';
172
192
 
173
- const MuiLoginForm = Component(() =>
193
+ const LoginForm = Component(() =>
174
194
  Div({
175
195
  maxWidth: '400px',
176
196
  margin: '0 auto',
177
197
  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
- }),
198
+ TextField({ label: 'Email', fullWidth: true }),
199
+ TextField({ label: 'Password', type: 'password' }),
189
200
  Button({
190
201
  variant: 'contained',
191
- color: 'primary',
192
202
  children: 'Sign In'
193
203
  })
194
204
  ]
@@ -196,9 +206,8 @@ const MuiLoginForm = Component(() =>
196
206
  );
197
207
  ```
198
208
 
199
- ### With Conditional Children That Contains Hook
200
-
201
- ```ts
209
+ ## Comprehensive Example: Theme-Switching & Conditional Components
210
+ ```tsx
202
211
  'use client'
203
212
  /**
204
213
  * This file showcases the integration of React hooks with @meonode/ui components
@@ -206,7 +215,7 @@ const MuiLoginForm = Component(() =>
206
215
  * approaches, the use of Higher-Order Components (HOCs), and how theme context
207
216
  * is managed and propagated within the @meonode/ui component tree.
208
217
  */
209
- import { Component, Column, Row, P, Node, Button, Theme, Center, NodeInstance } from '@meonode/ui'
218
+ import { Component, Column, Row, P, Node, Button, Theme, Center, NodeInstance, Absolute } from '@meonode/ui'
210
219
  import { useState, useEffect, ReactElement, ReactNode } from 'react'
211
220
  import { CssBaseline, FormControlLabel, TextField } from '@meonode/mui'
212
221
  import { Switch as MUISwitch } from '@mui/material'
@@ -322,7 +331,7 @@ const darkTheme: Theme = {
322
331
  */
323
332
  export default Component(() => {
324
333
  // State hook to control the visibility of additional content sections.
325
- const [showMore, setShowDetails] = useState(false) // 'showMore' controls visibility, 'setShowDetails' is the updater.
334
+ const [showMore, setShowDetails] = useState(false)
326
335
  const [mode, setMode] = useState<'dark' | 'light'>('light')
327
336
  const theme = mode === 'dark' ? darkTheme : lightTheme
328
337
 
@@ -344,6 +353,7 @@ export default Component(() => {
344
353
  backgroundColor: 'theme.background',
345
354
  color: 'theme.foreground',
346
355
  children: [
356
+ CssBaseline, // Applies baseline Material UI styles for consistent rendering.
347
357
  // Theme toggle switch using MUI components wrapped with @meonode/ui's Node HOC.
348
358
  Center({
349
359
  children: FormControlLabel({
@@ -355,6 +365,17 @@ export default Component(() => {
355
365
  onChange: () => setMode(prev => (prev === 'dark' ? 'light' : 'dark')),
356
366
  }),
357
367
  }),
368
+ // Button to show modal.
369
+ Button('Show Modal', {
370
+ onClick: () => Modal({ theme }), // Click handler to show modal immedietelly.
371
+ cursor: 'pointer', // Visual cue for clickability.
372
+ userSelect: 'none', // Prevents text selection on the button.
373
+ padding: '10px 20px',
374
+ backgroundColor: 'theme.primary', // Background color sourced from the theme context.
375
+ borderRadius: 5,
376
+ fontWeight: 'bold',
377
+ color: 'white',
378
+ }),
358
379
  // Button to toggle the visibility of the detail sections.
359
380
  Button(showMore ? 'Hide' : 'Show More', {
360
381
  onClick: () => setShowDetails(prev => !prev), // Click handler to toggle the 'showMore' state.
@@ -366,7 +387,6 @@ export default Component(() => {
366
387
  fontWeight: 'bold',
367
388
  color: 'white',
368
389
  }),
369
- CssBaseline, // Applies baseline Material UI styles for consistent rendering.
370
390
 
371
391
  /**
372
392
  * --- Unconditional Rendering Examples ---
@@ -500,28 +520,92 @@ const ReturnRenderedDetailComponent = ({ info }: { info: string }): ReactNode =>
500
520
  children: [P(info, { flex: 1, padding: '0 20px' }), TextField({ flex: 1, sx: { background: 'theme.primary' } })],
501
521
  }).render() // Explicitly renders to ReactNode.
502
522
  }
523
+
524
+ const Modal = ({ theme }: { theme: Theme }) => {
525
+ const modal = Absolute({
526
+ theme: theme.colors,
527
+ top: 0,
528
+ left: 0,
529
+ right: 0,
530
+ bottom: 0,
531
+ display: 'flex',
532
+ backgroundColor: 'rgba(0, 0, 0, 0.5)',
533
+ justifyContent: 'center',
534
+ alignItems: 'center',
535
+ onClick: e => {
536
+ if (e.target === e.currentTarget) {
537
+ modal?.unmount()
538
+ }
539
+ },
540
+ children: Column({
541
+ width: '50%',
542
+ height: '50%',
543
+ backgroundColor: 'theme.background',
544
+ borderRadius: '8px',
545
+ boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)',
546
+ transition: 'transform 0.2s ease-in-out',
547
+ padding: 10,
548
+ gap: 10,
549
+ color: 'theme.foreground',
550
+ children: [
551
+ Center({ fontWeight: 'bold', children: 'Hello There' }),
552
+ TextField({
553
+ sx: {
554
+ '& .MuiFormLabel-root': {
555
+ color: 'theme.foreground',
556
+ '&.Mui-focused': {
557
+ color: 'theme.foreground',
558
+ },
559
+ },
560
+ '& .MuiOutlinedInput-root': {
561
+ color: 'theme.foreground',
562
+ '& fieldset': {
563
+ borderColor: 'theme.foreground',
564
+ },
565
+ '&:hover fieldset': {
566
+ borderColor: 'theme.foreground',
567
+ },
568
+ '&.Mui-focused fieldset': {
569
+ borderColor: 'theme.foreground',
570
+ },
571
+ borderRadius: 2,
572
+ },
573
+ },
574
+ label: 'Hello',
575
+ fullWidth: true,
576
+ }),
577
+ ],
578
+ }),
579
+ }).toPortal()
580
+ }
503
581
  ```
504
582
 
583
+ ---
584
+
505
585
  ## API Reference
506
586
 
507
587
  ### Core Functions
508
588
 
509
- | Function | Parameters | Description |
510
- |----------------|-----------------------------------------|-------------------------------------------------|
511
- | `Node` | `element: string \| Component`, `props` | Creates a new UI node |
512
- | `Component` | `(props) => Node \| ReactNode` | Converts node trees to React components |
589
+ | Function | Parameters | Description |
590
+ |-------------|-----------------------------------------|----------------------------------------------|
591
+ | `Node` | `element: string | React.ComponentType`, `baseProps: object` | Creates a configurable UI node |
592
+ | `Component` | `(props: P) => Node | ReactNode` | Converts node trees to React components |
513
593
 
594
+ ---
514
595
 
515
596
  ## Contributing
516
597
 
517
598
  We welcome contributions! Please follow these steps:
518
- 1. Fork the repository
519
- 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
520
- 3. Commit your changes
521
- 4. Push to the branch
522
- 5. Open a Pull Request
523
599
 
524
- Contact me on [Discord](https://discordapp.com/users/704803255561224264) for discussions.
600
+ 1. **Fork** the repository
601
+ 2. **Clone** your fork: `git clone https://github.com/your-username/meonode-ui.git`
602
+ 3. **Install dependencies**: `yarn install` (or npm/pnpm)
603
+ 4. **Create a feature branch**: `git checkout -b feature/amazing-feature`
604
+ 5. **Commit changes** with descriptive messages
605
+ 6. **Push** to your branch: `git push origin feature/amazing-feature`
606
+ 7. **Open a Pull Request**
607
+
608
+ For major changes, please open an issue first to discuss your proposal.
525
609
 
526
610
  ---
527
611
 
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.19",
4
+ "version": "0.1.20",
5
5
  "type": "module",
6
6
  "main": "./dist/main.js",
7
7
  "types": "./dist/main.d.ts",