lego-dom 1.3.4 → 1.5.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 (93) hide show
  1. package/CHANGELOG.md +72 -1
  2. package/main.js +48 -17
  3. package/main.min.js +2 -2
  4. package/package.json +1 -1
  5. package/parse-lego.js +2 -2
  6. package/vite-plugin.js +0 -14
  7. package/.github/workflows/deploy-docs.yml +0 -56
  8. package/.legodom +0 -87
  9. package/docs/.vitepress/config.js +0 -161
  10. package/docs/api/config.md +0 -95
  11. package/docs/api/define.md +0 -58
  12. package/docs/api/directives.md +0 -50
  13. package/docs/api/globals.md +0 -29
  14. package/docs/api/index.md +0 -30
  15. package/docs/api/lifecycle.md +0 -40
  16. package/docs/api/route.md +0 -37
  17. package/docs/api/vite-plugin.md +0 -58
  18. package/docs/contributing/01-welcome.md +0 -38
  19. package/docs/contributing/02-registry.md +0 -133
  20. package/docs/contributing/03-batcher.md +0 -110
  21. package/docs/contributing/04-reactivity.md +0 -87
  22. package/docs/contributing/05-caching.md +0 -59
  23. package/docs/contributing/06-init.md +0 -136
  24. package/docs/contributing/07-observer.md +0 -72
  25. package/docs/contributing/08-snap.md +0 -140
  26. package/docs/contributing/09-diffing.md +0 -69
  27. package/docs/contributing/10-studs.md +0 -78
  28. package/docs/contributing/11-scanner.md +0 -117
  29. package/docs/contributing/12-render.md +0 -138
  30. package/docs/contributing/13-directives.md +0 -243
  31. package/docs/contributing/14-events.md +0 -57
  32. package/docs/contributing/15-router.md +0 -57
  33. package/docs/contributing/16-state.md +0 -47
  34. package/docs/contributing/17-legodom.md +0 -48
  35. package/docs/contributing/index.md +0 -24
  36. package/docs/examples/form.md +0 -42
  37. package/docs/examples/index.md +0 -104
  38. package/docs/examples/routing.md +0 -409
  39. package/docs/examples/sfc-showcase.md +0 -34
  40. package/docs/examples/todo-app.md +0 -383
  41. package/docs/guide/cdn-usage.md +0 -354
  42. package/docs/guide/components.md +0 -418
  43. package/docs/guide/directives.md +0 -539
  44. package/docs/guide/directory-structure.md +0 -248
  45. package/docs/guide/faq.md +0 -210
  46. package/docs/guide/getting-started.md +0 -262
  47. package/docs/guide/index.md +0 -88
  48. package/docs/guide/lifecycle.md +0 -525
  49. package/docs/guide/quick-start.md +0 -49
  50. package/docs/guide/reactivity.md +0 -415
  51. package/docs/guide/routing.md +0 -334
  52. package/docs/guide/server-side.md +0 -134
  53. package/docs/guide/sfc.md +0 -464
  54. package/docs/guide/templating.md +0 -388
  55. package/docs/index.md +0 -160
  56. package/docs/public/logo.svg +0 -17
  57. package/docs/router/basic-routing.md +0 -103
  58. package/docs/router/cold-entry.md +0 -91
  59. package/docs/router/history.md +0 -69
  60. package/docs/router/index.md +0 -73
  61. package/docs/router/resolver.md +0 -74
  62. package/docs/router/surgical-swaps.md +0 -134
  63. package/docs/tutorial/01-project-setup.md +0 -152
  64. package/docs/tutorial/02-your-first-component.md +0 -226
  65. package/docs/tutorial/03-adding-routes.md +0 -279
  66. package/docs/tutorial/04-multi-page-app.md +0 -329
  67. package/docs/tutorial/05-state-and-globals.md +0 -285
  68. package/docs/tutorial/index.md +0 -40
  69. package/examples/vite-app/README.md +0 -71
  70. package/examples/vite-app/index.html +0 -42
  71. package/examples/vite-app/package.json +0 -18
  72. package/examples/vite-app/src/app.css +0 -3
  73. package/examples/vite-app/src/app.js +0 -29
  74. package/examples/vite-app/src/components/app-navbar.lego +0 -34
  75. package/examples/vite-app/src/components/customers/customer-details.lego +0 -24
  76. package/examples/vite-app/src/components/customers/customer-orders.lego +0 -21
  77. package/examples/vite-app/src/components/customers/order-list.lego +0 -55
  78. package/examples/vite-app/src/components/greeting-card.lego +0 -41
  79. package/examples/vite-app/src/components/sample-component.lego +0 -75
  80. package/examples/vite-app/src/components/shells/customers-shell.lego +0 -21
  81. package/examples/vite-app/src/components/side-menu.lego +0 -46
  82. package/examples/vite-app/src/components/todo-list.lego +0 -239
  83. package/examples/vite-app/src/components/widgets/user-card.lego +0 -27
  84. package/examples/vite-app/vite.config.js +0 -22
  85. package/tests/error.test.js +0 -74
  86. package/tests/main.test.js +0 -103
  87. package/tests/memory.test.js +0 -68
  88. package/tests/monitoring.test.js +0 -74
  89. package/tests/naming.test.js +0 -74
  90. package/tests/parse-lego.test.js +0 -65
  91. package/tests/security.test.js +0 -67
  92. package/tests/server.test.js +0 -114
  93. 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/)