elit 1.0.0-beta

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 ADDED
@@ -0,0 +1,348 @@
1
+ # Elit
2
+
3
+ A lightweight, zero-dependency library for building reactive web applications with direct DOM manipulation.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/elit.svg)](https://www.npmjs.com/package/elit)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ ## Why Elit?
9
+
10
+ - **Tiny Bundle Size**: ~5KB gzipped - no framework bloat
11
+ - **Zero Dependencies**: Pure TypeScript, no external dependencies
12
+ - **Direct DOM Manipulation**: No virtual DOM overhead
13
+ - **TypeScript First**: Full type safety out of the box
14
+ - **Reactive State**: Simple but powerful reactive state management
15
+ - **Modern Features**: Router, SSR, virtual scrolling, and more
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ npm install elit
21
+ ```
22
+
23
+ ## Features
24
+
25
+ - 🎯 **Lightweight**: Optimized for performance and small bundle size
26
+ - ⚡ **Reactive State**: Built-in reactive state management with `createState`
27
+ - 🔄 **Computed Values**: Automatic dependency tracking with `computed`
28
+ - 🎨 **CSS-in-JS**: Type-safe styling with `CreateStyle`
29
+ - 🛣️ **Client-Side Router**: Hash and history mode routing with dynamic parameters
30
+ - 📱 **Virtual Scrolling**: Handle 100k+ items efficiently
31
+ - 🖥️ **SSR Support**: Server-side rendering capabilities
32
+ - 🎭 **SVG & MathML**: Full support for SVG and MathML elements
33
+ - 🔧 **Utilities**: Throttle, debounce, and batch rendering
34
+ - 📦 **Tree-shakeable**: Import only what you need
35
+
36
+ ## Quick Start
37
+
38
+ ```typescript
39
+ import { div, h1, p, button, createState, reactive, domNode } from 'elit';
40
+
41
+ // Create reactive state
42
+ const count = createState(0);
43
+
44
+ // Create elements
45
+ const app = div({ className: 'app' },
46
+ h1('Hello Elit!'),
47
+ p('A lightweight DOM library'),
48
+ reactive(count, (value) =>
49
+ button({ onclick: () => count.value++ }, `Count: ${value}`)
50
+ )
51
+ );
52
+
53
+ // Render to DOM
54
+ domNode.render('#app', app);
55
+ ```
56
+
57
+ ## API
58
+
59
+ ### Element Factories
60
+
61
+ Create virtual DOM nodes using element factory functions:
62
+
63
+ ```typescript
64
+ import { div, span, a, button, input, form } from 'elit';
65
+
66
+ const element = div({ className: 'container' },
67
+ span('Hello'),
68
+ a({ href: '/about' }, 'About')
69
+ );
70
+ ```
71
+
72
+ ### State Management
73
+
74
+ ```typescript
75
+ import { createState, computed, effect } from 'elit';
76
+
77
+ // Create state
78
+ const name = createState('World');
79
+ const count = createState(0);
80
+
81
+ // Computed values
82
+ const greeting = computed([name], (n) => `Hello, ${n}!`);
83
+
84
+ // State with options
85
+ const throttledState = createState(0, { throttle: 100 });
86
+ const deepState = createState({ nested: { value: 1 } }, { deep: true });
87
+ ```
88
+
89
+ ### Reactive Rendering
90
+
91
+ ```typescript
92
+ import { reactive, text, bindValue } from 'elit';
93
+
94
+ const message = createState('Hello');
95
+
96
+ // Reactive element - re-renders when state changes
97
+ const display = reactive(message, (value) =>
98
+ div({ className: 'message' }, value)
99
+ );
100
+
101
+ // Reactive text
102
+ const label = text(message);
103
+
104
+ // Two-way binding for inputs
105
+ const inputEl = input({ type: 'text', ...bindValue(message) });
106
+ ```
107
+
108
+ ### Server-Side Rendering
109
+
110
+ ```typescript
111
+ import { div, p, renderToString } from 'elit';
112
+
113
+ const html = renderToString(
114
+ div({ className: 'app' },
115
+ p('Server rendered content')
116
+ ),
117
+ { pretty: true }
118
+ );
119
+ ```
120
+
121
+ ### Routing
122
+
123
+ ```typescript
124
+ import { createRouter, createRouterView, routerLink } from 'elit';
125
+
126
+ const router = createRouter({
127
+ mode: 'history', // or 'hash'
128
+ routes: [
129
+ { path: '/', component: () => div('Home') },
130
+ { path: '/about', component: () => div('About') },
131
+ { path: '/user/:id', component: (params) => div(`User ${params.id}`) }
132
+ ],
133
+ notFound: () => div('404 Not Found'),
134
+ beforeEach: (to, from, next) => {
135
+ // Navigation guard
136
+ console.log(`Navigating from ${from} to ${to}`);
137
+ next();
138
+ }
139
+ });
140
+
141
+ // Create navigation links
142
+ const nav = routerLink(router, { to: '/about' }, 'Go to About');
143
+
144
+ // Programmatic navigation
145
+ router.navigate('/user/123');
146
+ ```
147
+
148
+ ### CSS-in-JS with CreateStyle
149
+
150
+ ```typescript
151
+ import { CreateStyle } from 'elit';
152
+
153
+ const styles = new CreateStyle();
154
+
155
+ // Define styles
156
+ const buttonClass = styles.class('button', {
157
+ padding: '10px 20px',
158
+ backgroundColor: '#007bff',
159
+ color: 'white',
160
+ border: 'none',
161
+ borderRadius: '4px',
162
+ cursor: 'pointer',
163
+ '&:hover': {
164
+ backgroundColor: '#0056b3'
165
+ }
166
+ });
167
+
168
+ // Use in elements
169
+ const btn = button({ className: buttonClass }, 'Click me');
170
+ ```
171
+
172
+ ### Performance Utilities
173
+
174
+ ```typescript
175
+ import { batchRender, renderChunked, createVirtualList, throttle, debounce } from 'elit';
176
+
177
+ // Batch render multiple elements
178
+ batchRender('#container', elements);
179
+
180
+ // Chunked rendering for very large lists
181
+ renderChunked('#container', largeArray, 5000, (current, total) => {
182
+ console.log(`Rendered ${current}/${total}`);
183
+ });
184
+
185
+ // Virtual scrolling
186
+ const virtualList = createVirtualList(
187
+ container,
188
+ items,
189
+ (item, index) => div(item.name),
190
+ 50, // item height
191
+ 5 // buffer size
192
+ );
193
+
194
+ // Throttle and debounce
195
+ const throttledFn = throttle(handleScroll, 100);
196
+ const debouncedFn = debounce(handleInput, 300);
197
+ ```
198
+
199
+ ### JSON Rendering
200
+
201
+ ```typescript
202
+ import { renderJson, renderVNode, renderJsonToString } from 'elit';
203
+
204
+ // Render from JSON structure (tag, attributes, children)
205
+ renderJson('#app', {
206
+ tag: 'div',
207
+ attributes: { class: 'container' },
208
+ children: [
209
+ { tag: 'h1', children: 'Title' },
210
+ { tag: 'p', children: 'Content' }
211
+ ]
212
+ });
213
+
214
+ // Render from VNode JSON structure (tagName, props, children)
215
+ renderVNode('#app', {
216
+ tagName: 'div',
217
+ props: { className: 'container' },
218
+ children: [
219
+ { tagName: 'h1', children: ['Title'] }
220
+ ]
221
+ });
222
+ ```
223
+
224
+ ### Head Management
225
+
226
+ ```typescript
227
+ import { setTitle, addMeta, addLink, addStyle, renderToHead } from 'elit';
228
+
229
+ setTitle('My App');
230
+ addMeta({ name: 'description', content: 'My awesome app' });
231
+ addLink({ rel: 'stylesheet', href: '/styles.css' });
232
+ addStyle('body { margin: 0; }');
233
+ ```
234
+
235
+ ## Available Elements
236
+
237
+ ### HTML Elements (100+)
238
+ All standard HTML elements are available as factory functions:
239
+
240
+ **Layout**: `div`, `span`, `section`, `article`, `header`, `footer`, `nav`, `main`, `aside`
241
+
242
+ **Text**: `p`, `h1`-`h6`, `strong`, `em`, `code`, `pre`, `blockquote`, `hr`, `br`
243
+
244
+ **Forms**: `form`, `input`, `button`, `textarea`, `select`, `option`, `label`, `fieldset`, `legend`
245
+
246
+ **Lists**: `ul`, `ol`, `li`, `dl`, `dt`, `dd`
247
+
248
+ **Tables**: `table`, `thead`, `tbody`, `tfoot`, `tr`, `th`, `td`, `caption`, `colgroup`, `col`
249
+
250
+ **Media**: `img`, `video`, `audio`, `source`, `track`, `picture`, `canvas`, `svg`
251
+
252
+ **Links**: `a`, `link`, `meta`, `base`
253
+
254
+ **Semantic**: `time`, `progress`, `meter`, `details`, `summary`, `dialog`, `mark`, `abbr`
255
+
256
+ And many more...
257
+
258
+ ### SVG Elements
259
+ All SVG elements are prefixed with `svg`:
260
+
261
+ `svgSvg`, `svgCircle`, `svgRect`, `svgPath`, `svgLine`, `svgPolyline`, `svgPolygon`, `svgEllipse`, `svgG`, `svgText`, `svgDefs`, `svgLinearGradient`, `svgRadialGradient`, `svgStop`, `svgUse`, `svgSymbol`, and more.
262
+
263
+ ### MathML Elements
264
+ All MathML elements are prefixed with `math`:
265
+
266
+ `mathMath`, `mathMi`, `mathMn`, `mathMo`, `mathMfrac`, `mathMsqrt`, `mathMroot`, `mathMsup`, `mathMsub`, `mathMsubsup`, `mathMover`, `mathMunder`, `mathMunderover`, and more.
267
+
268
+ ## Browser Usage
269
+
270
+ When loaded via script tag, all exports are available on the `window` object:
271
+
272
+ ```html
273
+ <script src="https://unpkg.com/elit@latest/dist/index.global.js"></script>
274
+ <script>
275
+ const { div, span, createState, domNode } = window;
276
+ // or use DomLib global
277
+ const app = DomLib.div('Hello');
278
+ </script>
279
+ ```
280
+
281
+ ## Examples
282
+
283
+ ### Todo App
284
+
285
+ ```typescript
286
+ import { div, input, button, ul, li, createState, reactive, bindValue } from 'elit';
287
+
288
+ const todos = createState<string[]>([]);
289
+ const newTodo = createState('');
290
+
291
+ const TodoApp = div({ className: 'todo-app' },
292
+ div({ className: 'input-group' },
293
+ input({ type: 'text', placeholder: 'Add a todo...', ...bindValue(newTodo) }),
294
+ button({
295
+ onclick: () => {
296
+ if (newTodo.value.trim()) {
297
+ todos.value = [...todos.value, newTodo.value];
298
+ newTodo.value = '';
299
+ }
300
+ }
301
+ }, 'Add')
302
+ ),
303
+ reactive(todos, (items) =>
304
+ ul(
305
+ ...items.map((todo, index) =>
306
+ li(
307
+ todo,
308
+ button({
309
+ onclick: () => {
310
+ todos.value = todos.value.filter((_, i) => i !== index);
311
+ }
312
+ }, 'Delete')
313
+ )
314
+ )
315
+ )
316
+ )
317
+ );
318
+ ```
319
+
320
+ ### Counter with Computed Values
321
+
322
+ ```typescript
323
+ import { div, button, createState, computed, reactive } from 'elit';
324
+
325
+ const count = createState(0);
326
+ const doubled = computed([count], (c) => c * 2);
327
+ const isEven = computed([count], (c) => c % 2 === 0);
328
+
329
+ const Counter = div(
330
+ reactive(count, (c) => div(`Count: ${c}`)),
331
+ reactive(doubled, (d) => div(`Doubled: ${d}`)),
332
+ reactive(isEven, (even) => div(`Is even: ${even}`)),
333
+ button({ onclick: () => count.value++ }, 'Increment'),
334
+ button({ onclick: () => count.value-- }, 'Decrement')
335
+ );
336
+ ```
337
+
338
+ ## Documentation
339
+
340
+ For detailed documentation, examples, and guides, visit the official documentation (coming soon).
341
+
342
+ ## Contributing
343
+
344
+ Contributions are welcome! Please feel free to submit a Pull Request.
345
+
346
+ ## License
347
+
348
+ MIT