lego-dom 1.3.4 → 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 (91) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/main.js +24 -3
  3. package/package.json +1 -1
  4. package/vite-plugin.js +0 -14
  5. package/.github/workflows/deploy-docs.yml +0 -56
  6. package/.legodom +0 -87
  7. package/docs/.vitepress/config.js +0 -161
  8. package/docs/api/config.md +0 -95
  9. package/docs/api/define.md +0 -58
  10. package/docs/api/directives.md +0 -50
  11. package/docs/api/globals.md +0 -29
  12. package/docs/api/index.md +0 -30
  13. package/docs/api/lifecycle.md +0 -40
  14. package/docs/api/route.md +0 -37
  15. package/docs/api/vite-plugin.md +0 -58
  16. package/docs/contributing/01-welcome.md +0 -38
  17. package/docs/contributing/02-registry.md +0 -133
  18. package/docs/contributing/03-batcher.md +0 -110
  19. package/docs/contributing/04-reactivity.md +0 -87
  20. package/docs/contributing/05-caching.md +0 -59
  21. package/docs/contributing/06-init.md +0 -136
  22. package/docs/contributing/07-observer.md +0 -72
  23. package/docs/contributing/08-snap.md +0 -140
  24. package/docs/contributing/09-diffing.md +0 -69
  25. package/docs/contributing/10-studs.md +0 -78
  26. package/docs/contributing/11-scanner.md +0 -117
  27. package/docs/contributing/12-render.md +0 -138
  28. package/docs/contributing/13-directives.md +0 -243
  29. package/docs/contributing/14-events.md +0 -57
  30. package/docs/contributing/15-router.md +0 -57
  31. package/docs/contributing/16-state.md +0 -47
  32. package/docs/contributing/17-legodom.md +0 -48
  33. package/docs/contributing/index.md +0 -24
  34. package/docs/examples/form.md +0 -42
  35. package/docs/examples/index.md +0 -104
  36. package/docs/examples/routing.md +0 -409
  37. package/docs/examples/sfc-showcase.md +0 -34
  38. package/docs/examples/todo-app.md +0 -383
  39. package/docs/guide/cdn-usage.md +0 -354
  40. package/docs/guide/components.md +0 -418
  41. package/docs/guide/directives.md +0 -539
  42. package/docs/guide/directory-structure.md +0 -248
  43. package/docs/guide/faq.md +0 -210
  44. package/docs/guide/getting-started.md +0 -262
  45. package/docs/guide/index.md +0 -88
  46. package/docs/guide/lifecycle.md +0 -525
  47. package/docs/guide/quick-start.md +0 -49
  48. package/docs/guide/reactivity.md +0 -415
  49. package/docs/guide/routing.md +0 -334
  50. package/docs/guide/server-side.md +0 -134
  51. package/docs/guide/sfc.md +0 -464
  52. package/docs/guide/templating.md +0 -388
  53. package/docs/index.md +0 -160
  54. package/docs/public/logo.svg +0 -17
  55. package/docs/router/basic-routing.md +0 -103
  56. package/docs/router/cold-entry.md +0 -91
  57. package/docs/router/history.md +0 -69
  58. package/docs/router/index.md +0 -73
  59. package/docs/router/resolver.md +0 -74
  60. package/docs/router/surgical-swaps.md +0 -134
  61. package/docs/tutorial/01-project-setup.md +0 -152
  62. package/docs/tutorial/02-your-first-component.md +0 -226
  63. package/docs/tutorial/03-adding-routes.md +0 -279
  64. package/docs/tutorial/04-multi-page-app.md +0 -329
  65. package/docs/tutorial/05-state-and-globals.md +0 -285
  66. package/docs/tutorial/index.md +0 -40
  67. package/examples/vite-app/README.md +0 -71
  68. package/examples/vite-app/index.html +0 -42
  69. package/examples/vite-app/package.json +0 -18
  70. package/examples/vite-app/src/app.css +0 -3
  71. package/examples/vite-app/src/app.js +0 -29
  72. package/examples/vite-app/src/components/app-navbar.lego +0 -34
  73. package/examples/vite-app/src/components/customers/customer-details.lego +0 -24
  74. package/examples/vite-app/src/components/customers/customer-orders.lego +0 -21
  75. package/examples/vite-app/src/components/customers/order-list.lego +0 -55
  76. package/examples/vite-app/src/components/greeting-card.lego +0 -41
  77. package/examples/vite-app/src/components/sample-component.lego +0 -75
  78. package/examples/vite-app/src/components/shells/customers-shell.lego +0 -21
  79. package/examples/vite-app/src/components/side-menu.lego +0 -46
  80. package/examples/vite-app/src/components/todo-list.lego +0 -239
  81. package/examples/vite-app/src/components/widgets/user-card.lego +0 -27
  82. package/examples/vite-app/vite.config.js +0 -22
  83. package/tests/error.test.js +0 -74
  84. package/tests/main.test.js +0 -103
  85. package/tests/memory.test.js +0 -68
  86. package/tests/monitoring.test.js +0 -74
  87. package/tests/naming.test.js +0 -74
  88. package/tests/parse-lego.test.js +0 -65
  89. package/tests/security.test.js +0 -67
  90. package/tests/server.test.js +0 -114
  91. package/tests/syntax.test.js +0 -67
@@ -1,418 +0,0 @@
1
- # Components
2
-
3
- Learn how to create and use components in Lego.
4
-
5
- ## What is a Component?
6
-
7
- A component is a reusable, self-contained piece of UI with its own template, styles, and logic.
8
-
9
-
10
- ::: warning Note That
11
- `style` tags inside NON SFC components are inside the `<template>` tag. And outside the tag in SFCs.
12
- :::
13
-
14
-
15
- ```html
16
- <template b-id="user-badge">
17
- <style>
18
- self {
19
- display: inline-flex;
20
- align-items: center;
21
- gap: 0.5rem;
22
- padding: 0.5rem 1rem;
23
- background: #f0f0f0;
24
- border-radius: 20px;
25
- }
26
- .avatar {
27
- width: 32px;
28
- height: 32px;
29
- border-radius: 50%;
30
- }
31
- </style>
32
-
33
- <img class="avatar" src="[[ avatarUrl ]]" alt="[[ name ]]">
34
- <span>[[ name ]]</span>
35
- </template>
36
- ```
37
-
38
- ## Creating Components
39
-
40
- ### Method 1: HTML Templates
41
-
42
- Define components directly in your HTML with `<template b-id>`:
43
-
44
- ```html
45
- <template b-id="hello-world" b-data="{ name: 'Default User' }">
46
- <h1>Hello [[ name ]]!</h1>
47
- </template>
48
-
49
- <!-- Uses the default "Default User" -->
50
- <hello-world></hello-world>
51
-
52
- <!-- Overrides the default with "Alice" -->
53
- <hello-world b-data="{ name: 'Alice' }"></hello-world>
54
- ```
55
-
56
- ### Method 2: JavaScript
57
-
58
- Use `Lego.define()` for programmatic component creation:
59
-
60
- ```js
61
- Lego.define('hello-world', `
62
- <h1>Hello [[ name ]]!</h1>
63
- `, {
64
- name: 'Alice'
65
- });
66
- ```
67
-
68
- ### Method 3: Single File Components (.lego)
69
-
70
- With Vite, use `.lego` files:
71
-
72
- ```html
73
- <!-- hello-world.lego -->
74
- <template>
75
- <h1>Hello [[ name ]]!</h1>
76
- </template>
77
-
78
- <script>
79
- export default {
80
- name: 'Alice'
81
- }
82
- </script>
83
- ```
84
-
85
- ## Component State
86
-
87
- State is defined in the component's logic object:
88
-
89
- ```js
90
- {
91
- // Data properties
92
- count: 0,
93
- username: 'Alice',
94
- items: ['apple', 'banana'],
95
-
96
- // Methods
97
- increment() {
98
- this.count++;
99
- },
100
-
101
- addItem(item) {
102
- this.items.push(item);
103
- }
104
- }
105
- ```
106
-
107
- Access state in templates using `[[ ]]`:
108
-
109
- ```html
110
- <p>Count: [[ count ]]</p>
111
- <button @click="increment()">+1</button>
112
- ```
113
-
114
- ## Passing Data
115
-
116
- ### Via b-data Attribute
117
-
118
- ```html
119
- <user-card b-data="{
120
- name: 'Bob',
121
- email: 'bob@example.com',
122
- role: 'admin'
123
- }"></user-card>
124
- ```
125
-
126
- ### Data Merging (The Three Tiers)
127
-
128
- Lego uses a sophisticated three-tier merging strategy to initialize component state. This allows you to define defaults at the library level, customize them for a component type, and then override them for specific instances.
129
-
130
- The priority is as follows (**last one wins**):
131
-
132
- 1. **Tier 1: Script Logic** - Data defined in `Lego.define()` or exported from a `.lego` SFC.
133
- 2. **Tier 2: Template Defaults** - Data defined on the `<template b-data="...">` attribute.
134
- 3. **Tier 3: Instance Overrides** - Data defined on the actual component tag `<my-comp b-data="...">`.
135
-
136
- ### Example of Merging
137
-
138
- ```html
139
- <!-- 1. Script Logic (Defined in JS) -->
140
- <script>
141
- Lego.define('user-card', `...`, { role: 'guest', theme: 'light' });
142
- </script>
143
-
144
- <!-- 2. Template Defaults (Defined in HTML) -->
145
- <template b-id="user-card" b-data="{ role: 'member', name: 'Anonymous' }">
146
- ...
147
- </template>
148
-
149
- <!-- 3. Instance Overrides -->
150
- <user-card b-data="{ name: 'Alice' }"></user-card>
151
- ```
152
-
153
- In the example above, the final state for the component will be:
154
- - `role`: `'member'` (Template override beats Script)
155
- - `theme`: `'light'` (Only defined in Script)
156
- - `name`: `'Alice'` (Instance override beats Template)
157
-
158
- ## Component Communication
159
-
160
- ### Parent → Child (Props)
161
-
162
- Pass data via `b-data`:
163
-
164
- ```html
165
- <child-component b-data="{ title: parentData.title }"></child-component>
166
- ```
167
-
168
- ### Child → Parent (Events)
169
-
170
- Use `$emit()` to dispatch custom events:
171
-
172
- ```html
173
- <!-- Child component -->
174
- <button @click="$emit('save', { id: 123 })">Save</button>
175
- ```
176
-
177
- ```js
178
- // Parent listens
179
- document.querySelector('child-component')
180
- .addEventListener('save', (e) => {
181
- console.log('Saved:', e.detail); // { id: 123 }
182
- });
183
- ```
184
-
185
- ### Accessing Ancestors
186
-
187
- Use `$ancestors()` to read parent component state:
188
-
189
- ```html
190
- <!-- In nested component -->
191
- <p>App title: [[ $ancestors('app-root').title ]]</p>
192
- ```
193
-
194
- ::: warning Read-Only
195
- `$ancestors()` is for reading parent state, not mutating it.
196
- :::
197
-
198
- ## Component Composition
199
-
200
- ### Nesting Components
201
-
202
- ```html
203
- <template b-id="app-layout">
204
- <header>
205
- <app-header></app-header>
206
- </header>
207
- <main>
208
- <app-sidebar></app-sidebar>
209
- <app-content></app-content>
210
- </main>
211
- </template>
212
- ```
213
-
214
- ### Using Slots
215
-
216
- Standard Web Components slots work:
217
-
218
- ```html
219
- <template b-id="card-container">
220
- <div class="card">
221
- <slot name="header"></slot>
222
- <slot></slot>
223
- <slot name="footer"></slot>
224
- </div>
225
- </template>
226
-
227
- <!-- Usage -->
228
- <card-container>
229
- <h2 slot="header">Title</h2>
230
- <p>Main content</p>
231
- <button slot="footer">Action</button>
232
- </card-container>
233
- ```
234
-
235
- ## Shadow DOM
236
-
237
- All components use Shadow DOM for style encapsulation.
238
-
239
- ### Benefits
240
-
241
- ✅ **Scoped Styles** - CSS doesn't leak in or out
242
- ✅ **No Naming Conflicts** - ID/class names are isolated
243
- ✅ **Composability** - Components work without side effects
244
-
245
- ### Styling the Host
246
-
247
- Use `self` keyword (converts to `:host`):
248
-
249
- ```html
250
- <style>
251
- self {
252
- display: block;
253
- padding: 1rem;
254
- }
255
-
256
- self:hover {
257
- background: #f5f5f5;
258
- }
259
- </style>
260
- ```
261
-
262
- ## Lifecycle
263
-
264
- Components have three lifecycle hooks:
265
-
266
- ```js
267
- {
268
- mounted() {
269
- // Component added to DOM
270
- this.fetchData();
271
- },
272
-
273
- updated() {
274
- // State changed and re-rendered
275
- console.log('New count:', this.count);
276
- },
277
-
278
- unmounted() {
279
- // Component removed from DOM
280
- clearInterval(this.timer);
281
- }
282
- }
283
- ```
284
-
285
- See [Lifecycle Hooks](/guide/lifecycle) for details.
286
-
287
- ## Best Practices
288
-
289
- ### 1. Keep Components Small
290
-
291
- Each component should have a single responsibility.
292
-
293
- ✅ Good: `user-avatar`, `user-name`, `user-bio`
294
- ❌ Bad: `entire-user-profile-page`
295
-
296
- ### 2. Use Semantic Names
297
-
298
- Name components after what they represent:
299
-
300
- ✅ Good: `product-card`, `search-bar`
301
- ❌ Bad: `blue-box`, `flex-container`
302
-
303
- ### 3. Avoid Deep Nesting
304
-
305
- Keep component trees shallow (3-4 levels max):
306
-
307
- ```html
308
- app-root
309
- ├── app-header
310
- │ └── nav-menu
311
- ├── app-main
312
- │ └── content-area
313
- └── app-footer
314
- ```
315
-
316
- ### 4. Initialize State in mounted()
317
-
318
- Fetch data or set up timers in `mounted()`:
319
-
320
- ```js
321
- {
322
- data: null,
323
- mounted() {
324
- this.fetchData();
325
- },
326
- async fetchData() {
327
- this.data = await fetch('/api/data').then(r => r.json());
328
- }
329
- }
330
- ```
331
-
332
- ### 5. Clean Up in unmounted()
333
-
334
- Clear timers, remove listeners:
335
-
336
- ```js
337
- {
338
- timer: null,
339
- mounted() {
340
- this.timer = setInterval(() => this.tick(), 1000);
341
- },
342
- unmounted() {
343
- clearInterval(this.timer);
344
- }
345
- }
346
- ```
347
-
348
- ## Common Patterns
349
-
350
- ### Loading States
351
-
352
- ```html
353
- <div b-show="loading">Loading...</div>
354
- <div b-show="!loading && data">
355
- <h2>[[ data.title ]]</h2>
356
- <p>[[ data.content ]]</p>
357
- </div>
358
- <div b-show="!loading && error">
359
- Error: [[ error ]]
360
- </div>
361
- ```
362
-
363
- ### Form Components
364
-
365
- ```js
366
- {
367
- form: {
368
- username: '',
369
- email: '',
370
- password: ''
371
- },
372
- errors: {},
373
-
374
- validate() {
375
- this.errors = {};
376
- if (!this.form.username) {
377
- this.errors.username = 'Required';
378
- }
379
- if (!this.form.email.includes('@')) {
380
- this.errors.email = 'Invalid email';
381
- }
382
- return Object.keys(this.errors).length === 0;
383
- },
384
-
385
- submit() {
386
- if (this.validate()) {
387
- // Submit form
388
- }
389
- }
390
- }
391
- ```
392
-
393
- ### Computed Values
394
-
395
- Use methods for computed values:
396
-
397
- ```js
398
- {
399
- items: [
400
- { name: 'Apple', price: 1.20 },
401
- { name: 'Banana', price: 0.80 }
402
- ],
403
-
404
- total() {
405
- return this.items.reduce((sum, item) => sum + item.price, 0);
406
- }
407
- }
408
- ```
409
-
410
- ```html
411
- <p>Total: $[[ total().toFixed(2) ]]</p>
412
- ```
413
-
414
- ## Next Steps
415
-
416
- - Learn about [Reactivity](/guide/reactivity) in depth
417
- - Explore [Templating](/guide/templating) features
418
- - See [complete examples](/examples/)