lego-dom 1.3.3 → 1.4.0

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 (92) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/main.js +24 -3
  3. package/main.min.js +7 -0
  4. package/package.json +3 -1
  5. package/vite-plugin.js +0 -14
  6. package/.github/workflows/deploy-docs.yml +0 -56
  7. package/.legodom +0 -87
  8. package/docs/.vitepress/config.js +0 -162
  9. package/docs/api/config.md +0 -95
  10. package/docs/api/define.md +0 -58
  11. package/docs/api/directives.md +0 -50
  12. package/docs/api/globals.md +0 -29
  13. package/docs/api/index.md +0 -30
  14. package/docs/api/lifecycle.md +0 -40
  15. package/docs/api/route.md +0 -37
  16. package/docs/api/vite-plugin.md +0 -58
  17. package/docs/contributing/01-welcome.md +0 -38
  18. package/docs/contributing/02-registry.md +0 -133
  19. package/docs/contributing/03-batcher.md +0 -110
  20. package/docs/contributing/04-reactivity.md +0 -87
  21. package/docs/contributing/05-caching.md +0 -59
  22. package/docs/contributing/06-init.md +0 -136
  23. package/docs/contributing/07-observer.md +0 -72
  24. package/docs/contributing/08-snap.md +0 -140
  25. package/docs/contributing/09-diffing.md +0 -69
  26. package/docs/contributing/10-studs.md +0 -78
  27. package/docs/contributing/11-scanner.md +0 -117
  28. package/docs/contributing/12-render.md +0 -138
  29. package/docs/contributing/13-directives.md +0 -243
  30. package/docs/contributing/14-events.md +0 -57
  31. package/docs/contributing/15-router.md +0 -57
  32. package/docs/contributing/16-state.md +0 -47
  33. package/docs/contributing/17-legodom.md +0 -48
  34. package/docs/contributing/index.md +0 -24
  35. package/docs/examples/form.md +0 -42
  36. package/docs/examples/index.md +0 -104
  37. package/docs/examples/routing.md +0 -409
  38. package/docs/examples/sfc-showcase.md +0 -34
  39. package/docs/examples/todo-app.md +0 -383
  40. package/docs/guide/cdn-usage.md +0 -328
  41. package/docs/guide/components.md +0 -412
  42. package/docs/guide/directives.md +0 -539
  43. package/docs/guide/directory-structure.md +0 -248
  44. package/docs/guide/faq.md +0 -210
  45. package/docs/guide/getting-started.md +0 -262
  46. package/docs/guide/index.md +0 -88
  47. package/docs/guide/lifecycle.md +0 -525
  48. package/docs/guide/quick-start.md +0 -49
  49. package/docs/guide/reactivity.md +0 -415
  50. package/docs/guide/routing.md +0 -334
  51. package/docs/guide/server-side.md +0 -134
  52. package/docs/guide/sfc.md +0 -420
  53. package/docs/guide/templating.md +0 -388
  54. package/docs/index.md +0 -160
  55. package/docs/public/logo.svg +0 -17
  56. package/docs/router/basic-routing.md +0 -103
  57. package/docs/router/cold-entry.md +0 -91
  58. package/docs/router/history.md +0 -69
  59. package/docs/router/index.md +0 -73
  60. package/docs/router/resolver.md +0 -74
  61. package/docs/router/surgical-swaps.md +0 -134
  62. package/docs/tutorial/01-project-setup.md +0 -152
  63. package/docs/tutorial/02-your-first-component.md +0 -226
  64. package/docs/tutorial/03-adding-routes.md +0 -279
  65. package/docs/tutorial/04-multi-page-app.md +0 -329
  66. package/docs/tutorial/05-state-and-globals.md +0 -285
  67. package/docs/tutorial/index.md +0 -40
  68. package/examples/vite-app/README.md +0 -71
  69. package/examples/vite-app/index.html +0 -42
  70. package/examples/vite-app/package.json +0 -18
  71. package/examples/vite-app/src/app.css +0 -3
  72. package/examples/vite-app/src/app.js +0 -29
  73. package/examples/vite-app/src/components/app-navbar.lego +0 -34
  74. package/examples/vite-app/src/components/customers/customer-details.lego +0 -24
  75. package/examples/vite-app/src/components/customers/customer-orders.lego +0 -21
  76. package/examples/vite-app/src/components/customers/order-list.lego +0 -55
  77. package/examples/vite-app/src/components/greeting-card.lego +0 -41
  78. package/examples/vite-app/src/components/sample-component.lego +0 -75
  79. package/examples/vite-app/src/components/shells/customers-shell.lego +0 -21
  80. package/examples/vite-app/src/components/side-menu.lego +0 -46
  81. package/examples/vite-app/src/components/todo-list.lego +0 -239
  82. package/examples/vite-app/src/components/widgets/user-card.lego +0 -27
  83. package/examples/vite-app/vite.config.js +0 -22
  84. package/tests/error.test.js +0 -74
  85. package/tests/main.test.js +0 -103
  86. package/tests/memory.test.js +0 -68
  87. package/tests/monitoring.test.js +0 -74
  88. package/tests/naming.test.js +0 -74
  89. package/tests/parse-lego.test.js +0 -65
  90. package/tests/security.test.js +0 -67
  91. package/tests/server.test.js +0 -114
  92. package/tests/syntax.test.js +0 -67
@@ -1,539 +0,0 @@
1
- # Directives
2
-
3
- Directives are special attributes that add reactive behavior to elements.
4
-
5
- ## b-if
6
-
7
- Conditional rendering (adds/removes from DOM).
8
-
9
- ### Basic Usage
10
-
11
- ```html
12
- <p b-if="isLoggedIn">Welcome back!</p>
13
- <p b-if="!isLoggedIn">Please log in</p>
14
- ```
15
-
16
- ### With Expressions
17
-
18
- ```html
19
- <div b-if="count > 0">Count is [[ count ]]</div>
20
- <div b-if="items.length === 0">No items</div>
21
- ```
22
-
23
- ::: tip b-if vs b-show
24
- `b-if` adds or removes the element from the DOM.
25
- `b-show` toggles `display: none`.
26
-
27
- Use `b-if` if the condition rarely changes.
28
- Use `b-show` if you toggle often.
29
- :::
30
-
31
- ## b-show
32
-
33
- Conditional rendering using `display: none`.
34
-
35
- ### Basic Usage
36
-
37
- ```html
38
- <p b-show="isLoggedIn">Welcome back!</p>
39
- <p b-show="!isLoggedIn">Please log in</p>
40
- ```
41
-
42
- ### With Expressions
43
-
44
- ```html
45
- <div b-show="count > 0">Count is [[ count ]]</div>
46
- <div b-show="items.length === 0">No items</div>
47
- <div b-show="user && user.role === 'admin'">Admin panel</div>
48
- ```
49
-
50
- ### Multiple Conditions
51
-
52
- ```html
53
- <p b-show="isLoggedIn && isPremium">Premium content</p>
54
- <p b-show="age >= 18 || hasParentConsent">Access granted</p>
55
- ```
56
-
57
- ::: tip How it Works
58
- `b-show` sets `display: none` when the condition is false. The element stays in the DOM but is hidden.
59
- :::
60
-
61
- ## b-html
62
-
63
- Renders raw HTML content.
64
-
65
- > [!WARNING]
66
- > Only use on trusted content. This exposes you to XSS vulnerabilities if used with user input.
67
-
68
- ```html
69
- <div b-html="rawContent"></div>
70
- ```
71
-
72
- ```js
73
- {
74
- rawContent: '<b>Bold</b> and <i>Italic</i>'
75
- }
76
- ```
77
-
78
- ## b-text
79
-
80
- Sets the text content of an element.
81
-
82
- > [!WARNING] Limitation
83
- > **`b-text` is extremely weak.** Unlike `[[ ]]`, it **does not** support JavaScript expressions (math, logic, functions). It ONLY supports simple property paths.
84
-
85
- ### Functionality
86
-
87
- | Syntax | Supported? | Example |
88
- | :--- | :--- | :--- |
89
- | **Property Path** | Yes | `b-text="user.name"` |
90
- | **Math** | No | `b-text="count + 1"` |
91
- | **Logic** | No | `b-text="isActive ? 'Yes' : 'No'"` |
92
- | **Methods** | No | `b-text="formatDate(date)"` |
93
-
94
- Use `[[ ]]` for anything complex. `b-text` is strictly for direct property binding.
95
-
96
- ```html
97
- <!-- Works -->
98
- <span b-text="user.name"></span>
99
-
100
- <!-- Does NOT Work (Use [[ ]] instead) -->
101
- <span b-text="user.firstName + ' ' + user.lastName"></span>
102
- <span b-text="count + 1"></span>
103
- ```
104
-
105
- ## b-var
106
-
107
- Creates a reference to a DOM element accessible via `this.$vars`.
108
-
109
- Use `b-var` when you need direct DOM access (e.g., `.focus()`, `.click()`, `.play()`).
110
-
111
- ### Usage
112
-
113
- ```html
114
- <input type="file" b-var="fileInput" style="display:none">
115
- <button @click="$vars.fileInput.click()">Upload</button>
116
- ```
117
-
118
- Or in script:
119
-
120
- ```javascript
121
- export default {
122
- openPicker() {
123
- this.$vars.fileInput.click();
124
- }
125
- }
126
- ```
127
-
128
- ## b-for
129
-
130
- List rendering.
131
-
132
- ### Basic Syntax
133
-
134
- ```html
135
- <ul>
136
- <li b-for="item in items">[[ item ]]</li>
137
- </ul>
138
- ```
139
-
140
- ### With Objects
141
-
142
- ```html
143
- <ul>
144
- <li b-for="todo in todos">
145
- [[ todo.text ]] - [[ todo.done ? 'Done' : 'Pending' ]]
146
- </li>
147
- </ul>
148
- ```
149
-
150
- ### Accessing Index
151
-
152
- Use `$index` (implicit variable):
153
-
154
- ```html
155
- <ul>
156
- <li b-for="item in items">
157
- #[[ $index + 1 ]]: [[ item.name ]]
158
- </li>
159
- </ul>
160
- ```
161
-
162
- ### Nested Loops
163
-
164
- ```html
165
- <div b-for="category in categories">
166
- <h3>[[ category.name ]]</h3>
167
- <ul>
168
- <li b-for="product in category.products">
169
- [[ product.name ]]
170
- </li>
171
- </ul>
172
- </div>
173
- ```
174
-
175
- ### With Conditionals
176
-
177
- ```html
178
- <li b-for="user in users">
179
- <span b-show="user.active">✅ [[ user.name ]]</span>
180
- <span b-show="!user.active">❌ [[ user.name ]]</span>
181
- </li>
182
- ```
183
-
184
- ## b-sync
185
-
186
- Two-way data binding for form inputs.
187
-
188
- ### Text Input
189
-
190
- ```html
191
- <input b-sync="username" placeholder="Enter username">
192
- <p>Hello, [[ username ]]!</p>
193
- ```
194
-
195
- ### Checkbox
196
-
197
- ```html
198
- <input type="checkbox" b-sync="agreed">
199
- <p b-show="agreed">You agreed to the terms</p>
200
- ```
201
-
202
- ### Radio Buttons
203
-
204
- ```html
205
- <input type="radio" name="size" value="small" b-sync="selectedSize">
206
- <input type="radio" name="size" value="medium" b-sync="selectedSize">
207
- <input type="radio" name="size" value="large" b-sync="selectedSize">
208
- <p>Selected: [[ selectedSize ]]</p>
209
- ```
210
-
211
- ### Select Dropdown
212
-
213
- ```html
214
- <select b-sync="country">
215
- <option value="us">United States</option>
216
- <option value="uk">United Kingdom</option>
217
- <option value="ca">Canada</option>
218
- </select>
219
- <p>Country: [[ country ]]</p>
220
- ```
221
-
222
- ### Textarea
223
-
224
- ```html
225
- <textarea b-sync="message" rows="4"></textarea>
226
- <p>[[ message.length ]] characters</p>
227
- ```
228
-
229
- ### In b-for Loops
230
-
231
- ```html
232
- <li b-for="todo in todos">
233
- <input type="checkbox" b-sync="todo.done">
234
- <span class="[[ todo.done ? 'done' : '' ]]">[[ todo.text ]]</span>
235
- </li>
236
- ```
237
-
238
- ## @event
239
-
240
- Event handlers.
241
-
242
- ### Common Events
243
-
244
- ```html
245
- <!-- Click -->
246
- <button @click="handleClick()">Click Me</button>
247
-
248
- <!-- Input -->
249
- <input @input="handleInput()">
250
-
251
- <!-- Change -->
252
- <select @change="handleChange()">...</select>
253
-
254
- <!-- Submit -->
255
- <form @submit="handleSubmit(event)">...</form>
256
-
257
- <!-- Focus/Blur -->
258
- <input @focus="onFocus()" @blur="onBlur()">
259
-
260
- <!-- Mouse Events -->
261
- <div @mouseenter="onHover()" @mouseleave="onLeave()">Hover me</div>
262
-
263
- <!-- Keyboard -->
264
- <input @keyup="onKeyUp(event)" @keydown="onKeyDown(event)">
265
- ```
266
-
267
- ### Event Object
268
-
269
- Access the native event object:
270
-
271
- ```html
272
- <button @click="handleClick(event)">Click</button>
273
- ```
274
-
275
- ```js
276
- {
277
- handleClick(event) {
278
- console.log('Target:', event.target);
279
- console.log('Type:', event.type);
280
- event.preventDefault();
281
- event.stopPropagation();
282
- }
283
- }
284
- ```
285
-
286
- ### Inline Expressions
287
-
288
- ```html
289
- <button @click="count++">Increment</button>
290
- <button @click="items.push('new item')">Add Item</button>
291
- <button @click="$emit('save', { id: 123 })">Save</button>
292
- ```
293
-
294
- ### Key Events
295
-
296
- ```html
297
- <input @keyup="event.key === 'Enter' && submit()">
298
- <input @keydown="event.key === 'Escape' && cancel()">
299
- ```
300
-
301
- ## b-link
302
-
303
- Client-side navigation (prevents page reload).
304
-
305
- ### Basic Usage
306
-
307
- ```html
308
- <a href="/" b-link>Home</a>
309
- <a href="/about" b-link>About</a>
310
- <a href="/contact" b-link>Contact</a>
311
- ```
312
-
313
- ### With Dynamic Routes
314
-
315
- ```html
316
- <a href="/user/[[ userId ]]" b-link>View Profile</a>
317
- <a href="/product/[[ productId ]]" b-link>[[ productName ]]</a>
318
- ```
319
-
320
- ::: tip Router Required
321
- `b-link` only works if you've set up routing with `Lego.route()`.
322
- :::
323
-
324
- ## b-data
325
-
326
- Initialize component state.
327
-
328
- ### Basic Usage
329
-
330
- ```html
331
- <my-component b-data="{ count: 0, name: 'Alice' }"></my-component>
332
- ```
333
-
334
- ### With Complex Data
335
-
336
- ```html
337
- <todo-list b-data="{
338
- todos: [
339
- { text: 'Learn Lego', done: true },
340
- { text: 'Build app', done: false }
341
- ],
342
- filter: 'all'
343
- }"></todo-list>
344
- ```
345
-
346
- ### Merging with Defaults
347
-
348
- ```js
349
- // Component definition
350
- Lego.define('user-card', `...`, {
351
- name: 'Guest', // Default
352
- role: 'user' // Default
353
- });
354
- ```
355
-
356
- ```html
357
- <!-- Only name is overridden -->
358
- <user-card b-data="{ name: 'Alice' }"></user-card>
359
- <!-- role remains 'user' -->
360
- ```
361
-
362
- ## Combining Directives
363
-
364
- ### b-show + b-for
365
-
366
- ```html
367
- <li b-for="item in items" b-show="item.visible">
368
- [[ item.name ]]
369
- </li>
370
- ```
371
-
372
- ### b-for + b-sync
373
-
374
- ```html
375
- <li b-for="todo in todos">
376
- <input type="checkbox" b-sync="todo.done">
377
- [[ todo.text ]]
378
- </li>
379
- ```
380
-
381
- ### Multiple Events
382
-
383
- ```html
384
- <input
385
- @input="handleInput()"
386
- @focus="onFocus()"
387
- @blur="onBlur()">
388
- ```
389
-
390
- ## Best Practices
391
-
392
- ### 1. Use b-show for Show/Hide
393
-
394
- ```html
395
- <!-- ✅ Clean -->
396
- <div b-show="showPanel">Panel content</div>
397
-
398
- <!-- ❌ Verbose -->
399
- <div style="display: [[ showPanel ? 'block' : 'none' ]]">Panel content</div>
400
- ```
401
-
402
- ### 2. Keep Event Handlers Simple
403
-
404
- ```html
405
- <!-- ✅ Good -->
406
- <button @click="increment()">+1</button>
407
-
408
- <!-- ❌ Too much logic -->
409
- <button @click="count++; total = count * price; updateDisplay()">Calculate</button>
410
- ```
411
-
412
- Move complex logic to methods.
413
-
414
- ### 3. Use b-sync for Forms
415
-
416
- ```html
417
- <!-- ✅ Declarative -->
418
- <input b-sync="username">
419
-
420
- <!-- ❌ Imperative -->
421
- <input @input="username = event.target.value">
422
- ```
423
-
424
- ### 4. Avoid Deep Nesting in b-for
425
-
426
- ```html
427
- <!-- ❌ Hard to read -->
428
- <div b-for="cat in categories">
429
- <div b-for="sub in cat.subcategories">
430
- <div b-for="item in sub.items">...</div>
431
- </div>
432
- </div>
433
-
434
- <!-- ✅ Break into components -->
435
- <category-list></category-list>
436
- ```
437
-
438
- ## Performance Tips
439
-
440
- ### b-show vs CSS
441
-
442
- `b-show` is fine for most cases, but for frequently toggled elements, use CSS:
443
-
444
- ```html
445
- <!-- For frequent toggling -->
446
- <div class="[[ visible ? '' : 'hidden' ]]">Content</div>
447
- ```
448
-
449
- ```css
450
- .hidden {
451
- display: none;
452
- }
453
- ```
454
-
455
- ### Limit b-for Items
456
-
457
- Paginate large lists:
458
-
459
- ```js
460
- {
461
- allItems: [...], // 1000 items
462
- currentPage: 1,
463
- itemsPerPage: 20,
464
-
465
- visibleItems() {
466
- const start = (this.currentPage - 1) * this.itemsPerPage;
467
- return this.allItems.slice(start, start + this.itemsPerPage);
468
- }
469
- }
470
- ```
471
-
472
- ```html
473
- <li b-for="item in visibleItems()">[[ item.name ]]</li>
474
- ```
475
-
476
- ## Common Patterns
477
-
478
- ### Toggle
479
-
480
- ```html
481
- <button @click="visible = !visible">Toggle</button>
482
- <div b-show="visible">Content</div>
483
- ```
484
-
485
- ### Counter
486
-
487
- ```html
488
- <button @click="count--">-</button>
489
- <span>[[ count ]]</span>
490
- <button @click="count++">+</button>
491
- ```
492
-
493
- ### Todo List
494
-
495
- ```html
496
- <input b-sync="newTodo" @keyup="event.key === 'Enter' && addTodo()">
497
- <ul>
498
- <li b-for="todo in todos">
499
- <input type="checkbox" b-sync="todo.done">
500
- <span class="[[ todo.done ? 'done' : '' ]]">[[ todo.text ]]</span>
501
- </li>
502
- </ul>
503
- ```
504
-
505
- ### Tabs
506
-
507
- ```html
508
- <nav>
509
- <button @click="activeTab = 'home'">Home</button>
510
- <button @click="activeTab = 'profile'">Profile</button>
511
- <button @click="activeTab = 'settings'">Settings</button>
512
- </nav>
513
-
514
- <div b-show="activeTab === 'home'">Home content</div>
515
- <div b-show="activeTab === 'profile'">Profile content</div>
516
- <div b-show="activeTab === 'settings'">Settings content</div>
517
- ```
518
-
519
- ## See Also
520
-
521
- Some directives are specific to certain features and are documented in their respective guides:
522
-
523
- ### Component Directives
524
-
525
- - **`b-id`**: Defines a component from a template.
526
- - **`b-styles`**: Applies shared styles to a component.
527
- - See [Components Guide](/guide/components)
528
-
529
- ### Routing Directives
530
-
531
- - **`b-target`**: Specifies the target element for surgical routing updates.
532
- - **`b-link`**: Controls browser history behavior for links.
533
- - See [Routing Guide](/guide/routing)
534
-
535
- ## Next Steps
536
-
537
- - See [directive examples](/examples/)
538
- - Learn about [event handling](/guide/directives#event)
539
- - Explore [form patterns](/examples/form)