lego-dom 0.0.7 → 0.0.9

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 (147) hide show
  1. package/.github/workflows/deploy-docs.yml +56 -0
  2. package/LICENSE +21 -0
  3. package/README.md +52 -314
  4. package/docs/.vitepress/config.js +107 -0
  5. package/docs/.vitepress/dist/404.html +22 -0
  6. package/docs/.vitepress/dist/api/define.html +35 -0
  7. package/docs/.vitepress/dist/api/directives.html +32 -0
  8. package/docs/.vitepress/dist/api/globals.html +27 -0
  9. package/docs/.vitepress/dist/api/index.html +25 -0
  10. package/docs/.vitepress/dist/api/lifecycle.html +38 -0
  11. package/docs/.vitepress/dist/api/route.html +34 -0
  12. package/docs/.vitepress/dist/api/vite-plugin.html +37 -0
  13. package/docs/.vitepress/dist/assets/api_define.md.UA-ygUnQ.js +11 -0
  14. package/docs/.vitepress/dist/assets/api_define.md.UA-ygUnQ.lean.js +1 -0
  15. package/docs/.vitepress/dist/assets/api_directives.md.BV-D251p.js +8 -0
  16. package/docs/.vitepress/dist/assets/api_directives.md.BV-D251p.lean.js +1 -0
  17. package/docs/.vitepress/dist/assets/api_globals.md.CEznyRAY.js +3 -0
  18. package/docs/.vitepress/dist/assets/api_globals.md.CEznyRAY.lean.js +1 -0
  19. package/docs/.vitepress/dist/assets/api_index.md.IEYUxUIr.js +1 -0
  20. package/docs/.vitepress/dist/assets/api_index.md.IEYUxUIr.lean.js +1 -0
  21. package/docs/.vitepress/dist/assets/api_lifecycle.md.Ccm5xw6-.js +14 -0
  22. package/docs/.vitepress/dist/assets/api_lifecycle.md.Ccm5xw6-.lean.js +1 -0
  23. package/docs/.vitepress/dist/assets/api_route.md.CAHf_KNp.js +10 -0
  24. package/docs/.vitepress/dist/assets/api_route.md.CAHf_KNp.lean.js +1 -0
  25. package/docs/.vitepress/dist/assets/api_vite-plugin.md.DC8Li09k.js +13 -0
  26. package/docs/.vitepress/dist/assets/api_vite-plugin.md.DC8Li09k.lean.js +1 -0
  27. package/docs/.vitepress/dist/assets/app.BfblNDJy.js +1 -0
  28. package/docs/.vitepress/dist/assets/chunks/@localSearchIndexroot.Crdp7-Zp.js +1 -0
  29. package/docs/.vitepress/dist/assets/chunks/VPLocalSearchBox.C18E44rY.js +9 -0
  30. package/docs/.vitepress/dist/assets/chunks/framework.B7OFBR9X.js +19 -0
  31. package/docs/.vitepress/dist/assets/chunks/theme.VX3itTW6.js +2 -0
  32. package/docs/.vitepress/dist/assets/examples_form.md.DQoAgbLR.js +34 -0
  33. package/docs/.vitepress/dist/assets/examples_form.md.DQoAgbLR.lean.js +1 -0
  34. package/docs/.vitepress/dist/assets/examples_index.md.CVJJjXXE.js +28 -0
  35. package/docs/.vitepress/dist/assets/examples_index.md.CVJJjXXE.lean.js +1 -0
  36. package/docs/.vitepress/dist/assets/examples_routing.md.sRnA5RXw.js +338 -0
  37. package/docs/.vitepress/dist/assets/examples_routing.md.sRnA5RXw.lean.js +1 -0
  38. package/docs/.vitepress/dist/assets/examples_sfc-showcase.md.DPf9Wm99.js +13 -0
  39. package/docs/.vitepress/dist/assets/examples_sfc-showcase.md.DPf9Wm99.lean.js +1 -0
  40. package/docs/.vitepress/dist/assets/examples_todo-app.md.CqF4JaWn.js +297 -0
  41. package/docs/.vitepress/dist/assets/examples_todo-app.md.CqF4JaWn.lean.js +1 -0
  42. package/docs/.vitepress/dist/assets/guide_cdn-usage.md.CjIjusre.js +182 -0
  43. package/docs/.vitepress/dist/assets/guide_cdn-usage.md.CjIjusre.lean.js +1 -0
  44. package/docs/.vitepress/dist/assets/guide_components.md.CMU3iM6R.js +174 -0
  45. package/docs/.vitepress/dist/assets/guide_components.md.CMU3iM6R.lean.js +1 -0
  46. package/docs/.vitepress/dist/assets/guide_contributing.md.Crrv3T_0.js +1 -0
  47. package/docs/.vitepress/dist/assets/guide_contributing.md.Crrv3T_0.lean.js +1 -0
  48. package/docs/.vitepress/dist/assets/guide_directives.md.DFwqvqOv.js +140 -0
  49. package/docs/.vitepress/dist/assets/guide_directives.md.DFwqvqOv.lean.js +1 -0
  50. package/docs/.vitepress/dist/assets/guide_getting-started.md.DtaJPe0i.js +107 -0
  51. package/docs/.vitepress/dist/assets/guide_getting-started.md.DtaJPe0i.lean.js +1 -0
  52. package/docs/.vitepress/dist/assets/guide_index.md.DtJVpLI9.js +2 -0
  53. package/docs/.vitepress/dist/assets/guide_index.md.DtJVpLI9.lean.js +1 -0
  54. package/docs/.vitepress/dist/assets/guide_lifecycle.md.CfY3jlU1.js +304 -0
  55. package/docs/.vitepress/dist/assets/guide_lifecycle.md.CfY3jlU1.lean.js +1 -0
  56. package/docs/.vitepress/dist/assets/guide_quick-start.md.CwdNNA21.js +33 -0
  57. package/docs/.vitepress/dist/assets/guide_quick-start.md.CwdNNA21.lean.js +1 -0
  58. package/docs/.vitepress/dist/assets/guide_reactivity.md.DgTH0MTn.js +135 -0
  59. package/docs/.vitepress/dist/assets/guide_reactivity.md.DgTH0MTn.lean.js +1 -0
  60. package/docs/.vitepress/dist/assets/guide_routing.md.nMB0QOBR.js +193 -0
  61. package/docs/.vitepress/dist/assets/guide_routing.md.nMB0QOBR.lean.js +1 -0
  62. package/docs/.vitepress/dist/assets/guide_sfc.md.BUkWma1z.js +187 -0
  63. package/docs/.vitepress/dist/assets/guide_sfc.md.BUkWma1z.lean.js +1 -0
  64. package/docs/.vitepress/dist/assets/guide_templating.md.XI3uUlYI.js +119 -0
  65. package/docs/.vitepress/dist/assets/guide_templating.md.XI3uUlYI.lean.js +1 -0
  66. package/docs/.vitepress/dist/assets/index.md.M4_o26kF.js +23 -0
  67. package/docs/.vitepress/dist/assets/index.md.M4_o26kF.lean.js +1 -0
  68. package/docs/.vitepress/dist/assets/inter-italic-cyrillic-ext.r48I6akx.woff2 +0 -0
  69. package/docs/.vitepress/dist/assets/inter-italic-cyrillic.By2_1cv3.woff2 +0 -0
  70. package/docs/.vitepress/dist/assets/inter-italic-greek-ext.1u6EdAuj.woff2 +0 -0
  71. package/docs/.vitepress/dist/assets/inter-italic-greek.DJ8dCoTZ.woff2 +0 -0
  72. package/docs/.vitepress/dist/assets/inter-italic-latin-ext.CN1xVJS-.woff2 +0 -0
  73. package/docs/.vitepress/dist/assets/inter-italic-latin.C2AdPX0b.woff2 +0 -0
  74. package/docs/.vitepress/dist/assets/inter-italic-vietnamese.BSbpV94h.woff2 +0 -0
  75. package/docs/.vitepress/dist/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2 +0 -0
  76. package/docs/.vitepress/dist/assets/inter-roman-cyrillic.C5lxZ8CY.woff2 +0 -0
  77. package/docs/.vitepress/dist/assets/inter-roman-greek-ext.CqjqNYQ-.woff2 +0 -0
  78. package/docs/.vitepress/dist/assets/inter-roman-greek.BBVDIX6e.woff2 +0 -0
  79. package/docs/.vitepress/dist/assets/inter-roman-latin-ext.4ZJIpNVo.woff2 +0 -0
  80. package/docs/.vitepress/dist/assets/inter-roman-latin.Di8DUHzh.woff2 +0 -0
  81. package/docs/.vitepress/dist/assets/inter-roman-vietnamese.BjW4sHH5.woff2 +0 -0
  82. package/docs/.vitepress/dist/assets/style.eycE2Jhw.css +1 -0
  83. package/docs/.vitepress/dist/examples/form.html +58 -0
  84. package/docs/.vitepress/dist/examples/index.html +52 -0
  85. package/docs/.vitepress/dist/examples/routing.html +362 -0
  86. package/docs/.vitepress/dist/examples/sfc-showcase.html +37 -0
  87. package/docs/.vitepress/dist/examples/todo-app.html +321 -0
  88. package/docs/.vitepress/dist/guide/cdn-usage.html +206 -0
  89. package/docs/.vitepress/dist/guide/components.html +198 -0
  90. package/docs/.vitepress/dist/guide/contributing.html +25 -0
  91. package/docs/.vitepress/dist/guide/directives.html +164 -0
  92. package/docs/.vitepress/dist/guide/getting-started.html +131 -0
  93. package/docs/.vitepress/dist/guide/index.html +26 -0
  94. package/docs/.vitepress/dist/guide/lifecycle.html +328 -0
  95. package/docs/.vitepress/dist/guide/quick-start.html +57 -0
  96. package/docs/.vitepress/dist/guide/reactivity.html +159 -0
  97. package/docs/.vitepress/dist/guide/routing.html +217 -0
  98. package/docs/.vitepress/dist/guide/sfc.html +211 -0
  99. package/docs/.vitepress/dist/guide/templating.html +143 -0
  100. package/docs/.vitepress/dist/hashmap.json +1 -0
  101. package/docs/.vitepress/dist/index.html +47 -0
  102. package/docs/.vitepress/dist/logo.svg +38 -0
  103. package/docs/.vitepress/dist/vp-icons.css +1 -0
  104. package/docs/api/define.md +31 -0
  105. package/docs/api/directives.md +42 -0
  106. package/docs/api/globals.md +29 -0
  107. package/docs/api/index.md +29 -0
  108. package/docs/api/lifecycle.md +40 -0
  109. package/docs/api/route.md +37 -0
  110. package/docs/api/vite-plugin.md +58 -0
  111. package/docs/examples/form.md +42 -0
  112. package/docs/examples/index.md +104 -0
  113. package/docs/examples/routing.md +409 -0
  114. package/docs/examples/sfc-showcase.md +34 -0
  115. package/docs/examples/todo-app.md +383 -0
  116. package/docs/guide/cdn-usage.md +320 -0
  117. package/docs/guide/components.md +394 -0
  118. package/docs/guide/contributing.md +32 -0
  119. package/docs/guide/directives.md +430 -0
  120. package/docs/guide/getting-started.md +233 -0
  121. package/docs/guide/index.md +88 -0
  122. package/docs/guide/lifecycle.md +493 -0
  123. package/docs/guide/quick-start.md +46 -0
  124. package/docs/guide/reactivity.md +394 -0
  125. package/docs/guide/routing.md +373 -0
  126. package/docs/guide/sfc.md +381 -0
  127. package/docs/guide/templating.md +383 -0
  128. package/docs/index.md +126 -0
  129. package/docs/public/logo.svg +17 -0
  130. package/examples/vite-app/README.md +71 -0
  131. package/examples/vite-app/index.html +49 -0
  132. package/examples/vite-app/package.json +16 -0
  133. package/examples/vite-app/src/components/greeting-card.lego +41 -0
  134. package/examples/vite-app/src/components/sample-component.lego +75 -0
  135. package/examples/vite-app/src/components/todo-list.lego +242 -0
  136. package/examples/vite-app/src/main.js +11 -0
  137. package/examples/vite-app/vite.config.js +17 -0
  138. package/examples.js +99 -0
  139. package/go.html +117 -0
  140. package/lego.js +2 -0
  141. package/main.js +41 -35
  142. package/package.json +39 -6
  143. package/parse-lego.js +119 -0
  144. package/parse-lego.test.js +107 -0
  145. package/vite-plugin.js +133 -0
  146. package/.ignore/auto.html +0 -135
  147. package/.ignore/test.html +0 -73
@@ -0,0 +1,383 @@
1
+ # Todo App Example
2
+
3
+ A complete todo application demonstrating Lego features.
4
+
5
+ ## Live Demo
6
+
7
+ <iframe src="/demos/todo-app.html" style="width:100%;height:500px;border:1px solid #ddd;border-radius:4px;"></iframe>
8
+
9
+ ## Full Source Code
10
+
11
+ ```html
12
+ <!DOCTYPE html>
13
+ <html lang="en">
14
+ <head>
15
+ <meta charset="UTF-8">
16
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
17
+ <title>Todo App - Lego</title>
18
+ <style>
19
+ body {
20
+ font-family: system-ui, -apple-system, sans-serif;
21
+ max-width: 600px;
22
+ margin: 2rem auto;
23
+ padding: 0 1rem;
24
+ background: #f5f5f5;
25
+ }
26
+ h1 {
27
+ text-align: center;
28
+ color: #333;
29
+ }
30
+ </style>
31
+ </head>
32
+ <body>
33
+ <h1>📝 Todo App</h1>
34
+
35
+ <todo-app></todo-app>
36
+
37
+ <script src="https://unpkg.com/lego-dom/main.js"></script>
38
+
39
+ <template b-id="todo-app">
40
+ <style>
41
+ self {
42
+ display: block;
43
+ background: white;
44
+ border-radius: 8px;
45
+ padding: 1.5rem;
46
+ box-shadow: 0 2px 8px rgba(0,0,0,0.1);
47
+ }
48
+
49
+ .input-group {
50
+ display: flex;
51
+ gap: 0.5rem;
52
+ margin-bottom: 1.5rem;
53
+ }
54
+
55
+ input[type="text"] {
56
+ flex: 1;
57
+ padding: 0.75rem;
58
+ font-size: 1rem;
59
+ border: 2px solid #e0e0e0;
60
+ border-radius: 4px;
61
+ }
62
+
63
+ input[type="text"]:focus {
64
+ outline: none;
65
+ border-color: #4CAF50;
66
+ }
67
+
68
+ .btn {
69
+ padding: 0.75rem 1.5rem;
70
+ font-size: 1rem;
71
+ border: none;
72
+ border-radius: 4px;
73
+ cursor: pointer;
74
+ font-weight: 600;
75
+ transition: background 0.2s;
76
+ }
77
+
78
+ .btn-primary {
79
+ background: #4CAF50;
80
+ color: white;
81
+ }
82
+
83
+ .btn-primary:hover {
84
+ background: #45a049;
85
+ }
86
+
87
+ .filters {
88
+ display: flex;
89
+ gap: 0.5rem;
90
+ margin-bottom: 1rem;
91
+ }
92
+
93
+ .filter-btn {
94
+ padding: 0.5rem 1rem;
95
+ background: #f0f0f0;
96
+ border: none;
97
+ border-radius: 4px;
98
+ cursor: pointer;
99
+ }
100
+
101
+ .filter-btn.active {
102
+ background: #4CAF50;
103
+ color: white;
104
+ }
105
+
106
+ ul {
107
+ list-style: none;
108
+ padding: 0;
109
+ margin: 0;
110
+ }
111
+
112
+ li {
113
+ display: flex;
114
+ align-items: center;
115
+ gap: 0.75rem;
116
+ padding: 0.75rem;
117
+ border-bottom: 1px solid #f0f0f0;
118
+ transition: background 0.2s;
119
+ }
120
+
121
+ li:hover {
122
+ background: #f9f9f9;
123
+ }
124
+
125
+ input[type="checkbox"] {
126
+ width: 20px;
127
+ height: 20px;
128
+ cursor: pointer;
129
+ }
130
+
131
+ .todo-text {
132
+ flex: 1;
133
+ font-size: 1rem;
134
+ }
135
+
136
+ .todo-text.done {
137
+ text-decoration: line-through;
138
+ color: #999;
139
+ }
140
+
141
+ .delete-btn {
142
+ padding: 0.25rem 0.5rem;
143
+ background: #f44336;
144
+ color: white;
145
+ border: none;
146
+ border-radius: 4px;
147
+ cursor: pointer;
148
+ font-size: 0.875rem;
149
+ }
150
+
151
+ .delete-btn:hover {
152
+ background: #da190b;
153
+ }
154
+
155
+ .stats {
156
+ margin-top: 1rem;
157
+ padding-top: 1rem;
158
+ border-top: 2px solid #f0f0f0;
159
+ display: flex;
160
+ justify-content: space-between;
161
+ color: #666;
162
+ font-size: 0.875rem;
163
+ }
164
+
165
+ .clear-completed {
166
+ background: none;
167
+ border: none;
168
+ color: #f44336;
169
+ cursor: pointer;
170
+ text-decoration: underline;
171
+ }
172
+ </style>
173
+
174
+ <div class="input-group">
175
+ <input
176
+ type="text"
177
+ b-sync="newTodo"
178
+ placeholder="What needs to be done?"
179
+ @keyup="event.key === 'Enter' && addTodo()">
180
+ <button class="btn btn-primary" @click="addTodo()">Add</button>
181
+ </div>
182
+
183
+ <div class="filters">
184
+ <button
185
+ class="filter-btn {{ filter === 'all' ? 'active' : '' }}"
186
+ @click="filter = 'all'">
187
+ All
188
+ </button>
189
+ <button
190
+ class="filter-btn {{ filter === 'active' ? 'active' : '' }}"
191
+ @click="filter = 'active'">
192
+ Active
193
+ </button>
194
+ <button
195
+ class="filter-btn {{ filter === 'completed' ? 'active' : '' }}"
196
+ @click="filter = 'completed'">
197
+ Completed
198
+ </button>
199
+ </div>
200
+
201
+ <ul>
202
+ <li b-for="todo in filteredTodos()">
203
+ <input type="checkbox" b-sync="todo.done">
204
+ <span class="todo-text {{ todo.done ? 'done' : '' }}">
205
+ {{ todo.text }}
206
+ </span>
207
+ <button class="delete-btn" @click="deleteTodo(todo)">Delete</button>
208
+ </li>
209
+ </ul>
210
+
211
+ <div class="stats">
212
+ <span>{{ remaining() }} item{{ remaining() === 1 ? '' : 's' }} left</span>
213
+ <button
214
+ class="clear-completed"
215
+ b-if="completedCount() > 0"
216
+ @click="clearCompleted()">
217
+ Clear completed ({{ completedCount() }})
218
+ </button>
219
+ </div>
220
+ </template>
221
+
222
+ <script>
223
+ Lego.define('todo-app',
224
+ document.querySelector('template[b-id="todo-app"]').innerHTML,
225
+ {
226
+ newTodo: '',
227
+ filter: 'all',
228
+ todos: [],
229
+
230
+ mounted() {
231
+ // Load from localStorage
232
+ const saved = localStorage.getItem('legojs-todos');
233
+ if (saved) {
234
+ this.todos = JSON.parse(saved);
235
+ }
236
+ },
237
+
238
+ updated() {
239
+ // Save to localStorage
240
+ localStorage.setItem('legojs-todos', JSON.stringify(this.todos));
241
+ },
242
+
243
+ addTodo() {
244
+ if (this.newTodo.trim()) {
245
+ this.todos.push({
246
+ id: Date.now(),
247
+ text: this.newTodo,
248
+ done: false
249
+ });
250
+ this.newTodo = '';
251
+ }
252
+ },
253
+
254
+ deleteTodo(todo) {
255
+ const index = this.todos.indexOf(todo);
256
+ if (index > -1) {
257
+ this.todos.splice(index, 1);
258
+ }
259
+ },
260
+
261
+ filteredTodos() {
262
+ if (this.filter === 'active') {
263
+ return this.todos.filter(t => !t.done);
264
+ } else if (this.filter === 'completed') {
265
+ return this.todos.filter(t => t.done);
266
+ }
267
+ return this.todos;
268
+ },
269
+
270
+ remaining() {
271
+ return this.todos.filter(t => !t.done).length;
272
+ },
273
+
274
+ completedCount() {
275
+ return this.todos.filter(t => t.done).length;
276
+ },
277
+
278
+ clearCompleted() {
279
+ this.todos = this.todos.filter(t => !t.done);
280
+ }
281
+ }
282
+ );
283
+ </script>
284
+ </body>
285
+ </html>
286
+ ```
287
+
288
+ ## Features Demonstrated
289
+
290
+ ### ✅ Reactivity
291
+ - Auto-updates when todos change
292
+ - Two-way binding with `b-sync`
293
+ - Computed values (`remaining()`, `completedCount()`)
294
+
295
+ ### ✅ List Rendering
296
+ - `b-for` to iterate over todos
297
+ - Dynamic filtering based on status
298
+
299
+ ### ✅ Event Handling
300
+ - Add on Enter key
301
+ - Click to complete/delete
302
+ - Filter buttons
303
+
304
+ ### ✅ Lifecycle Hooks
305
+ - `mounted()` - Load from localStorage
306
+ - `updated()` - Save to localStorage
307
+
308
+ ### ✅ Conditional Rendering
309
+ - Show/hide "Clear completed" button
310
+ - Different styles for completed items
311
+
312
+ ### ✅ Methods
313
+ - `addTodo()` - Add new item
314
+ - `deleteTodo()` - Remove item
315
+ - `filteredTodos()` - Filter logic
316
+ - `clearCompleted()` - Batch delete
317
+
318
+ ## Key Concepts
319
+
320
+ ### Local Storage Persistence
321
+
322
+ ```js
323
+ mounted() {
324
+ const saved = localStorage.getItem('legojs-todos');
325
+ if (saved) {
326
+ this.todos = JSON.parse(saved);
327
+ }
328
+ },
329
+
330
+ updated() {
331
+ localStorage.setItem('legojs-todos', JSON.stringify(this.todos));
332
+ }
333
+ ```
334
+
335
+ ### Filtering
336
+
337
+ ```js
338
+ filteredTodos() {
339
+ if (this.filter === 'active') {
340
+ return this.todos.filter(t => !t.done);
341
+ } else if (this.filter === 'completed') {
342
+ return this.todos.filter(t => t.done);
343
+ }
344
+ return this.todos;
345
+ }
346
+ ```
347
+
348
+ ### Array Manipulation
349
+
350
+ ```js
351
+ // Add
352
+ this.todos.push({ ... });
353
+
354
+ // Remove
355
+ this.todos.splice(index, 1);
356
+
357
+ // Filter (reassign)
358
+ this.todos = this.todos.filter(t => !t.done);
359
+ ```
360
+
361
+ ## Try It Yourself
362
+
363
+ 1. Copy the code above
364
+ 2. Save as `todo.html`
365
+ 3. Open in a browser
366
+ 4. Add todos, mark as complete, filter, delete
367
+ 5. Refresh—todos persist!
368
+
369
+ ## Extensions
370
+
371
+ Try adding these features:
372
+
373
+ - **Edit mode** - Double click to edit todo text
374
+ - **Due dates** - Add date picker and sort by date
375
+ - **Categories** - Organize todos into lists
376
+ - **Drag & drop** - Reorder todos
377
+ - **Export/Import** - Download/upload todo list
378
+
379
+ ## Next Steps
380
+
381
+ - See [Routing Example](/examples/routing)
382
+ - Learn about [Form Validation](/examples/form)
383
+ - Explore [SFC Showcase](/examples/sfc-showcase)
@@ -0,0 +1,320 @@
1
+ # CDN Usage
2
+
3
+ Lego works perfectly without any build tools. Just include it via CDN and start building!
4
+
5
+ ## Quick Start
6
+
7
+ ```html
8
+ <!DOCTYPE html>
9
+ <html>
10
+ <head>
11
+ <title>My App</title>
12
+ </head>
13
+ <body>
14
+ <!-- Define your component -->
15
+ <template b-id="hello-world">
16
+ <h1>{{ message }}</h1>
17
+ </template>
18
+
19
+ <!-- Use it -->
20
+ <hello-world b-data="{ message: 'Hello from CDN!' }"></hello-world>
21
+
22
+ <!-- Include Lego -->
23
+ <script src="https://unpkg.com/lego-dom/main.js"></script>
24
+ </body>
25
+ </html>
26
+ ```
27
+
28
+ That's it! Open this file in any browser and it works.
29
+
30
+ ## CDN Providers
31
+
32
+ ### unpkg (Recommended)
33
+
34
+ ```html
35
+ <!-- Latest version -->
36
+ <script src="https://unpkg.com/lego-dom/main.js"></script>
37
+
38
+ <!-- Specific version -->
39
+ <script src="https://unpkg.com/lego-dom@0.0.7/main.js"></script>
40
+ ```
41
+
42
+ ### jsdelivr
43
+
44
+ ```html
45
+ <!-- Latest version -->
46
+ <script src="https://cdn.jsdelivr.net/npm/lego-dom/main.js"></script>
47
+
48
+ <!-- Specific version -->
49
+ <script src="https://cdn.jsdelivr.net/npm/lego-dom@0.0.7/main.js"></script>
50
+ ```
51
+
52
+ ### cdnjs
53
+
54
+ ```html
55
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/lego-dom/0.0.7/main.js"></script>
56
+ ```
57
+
58
+ ## Complete Example
59
+
60
+ Here's a full working application using only CDN:
61
+
62
+ ```html
63
+ <!DOCTYPE html>
64
+ <html lang="en">
65
+ <head>
66
+ <meta charset="UTF-8">
67
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
68
+ <title>Todo App - Lego</title>
69
+ <style>
70
+ body {
71
+ font-family: system-ui, sans-serif;
72
+ max-width: 600px;
73
+ margin: 2rem auto;
74
+ padding: 0 1rem;
75
+ }
76
+ </style>
77
+ </head>
78
+ <body>
79
+ <h1>My Todo App</h1>
80
+ <todo-app></todo-app>
81
+
82
+ <template b-id="todo-app">
83
+ <style>
84
+ self {
85
+ display: block;
86
+ }
87
+ .input-group {
88
+ display: flex;
89
+ gap: 0.5rem;
90
+ margin-bottom: 1rem;
91
+ }
92
+ input {
93
+ flex: 1;
94
+ padding: 0.5rem;
95
+ font-size: 1rem;
96
+ }
97
+ button {
98
+ padding: 0.5rem 1rem;
99
+ font-size: 1rem;
100
+ background: #4CAF50;
101
+ color: white;
102
+ border: none;
103
+ cursor: pointer;
104
+ }
105
+ ul {
106
+ list-style: none;
107
+ padding: 0;
108
+ }
109
+ li {
110
+ padding: 0.75rem;
111
+ border-bottom: 1px solid #eee;
112
+ display: flex;
113
+ align-items: center;
114
+ gap: 0.5rem;
115
+ }
116
+ .done {
117
+ text-decoration: line-through;
118
+ opacity: 0.6;
119
+ }
120
+ </style>
121
+
122
+ <div class="input-group">
123
+ <input
124
+ b-sync="newTodo"
125
+ placeholder="What needs to be done?"
126
+ @keyup="event.key === 'Enter' && addTodo()">
127
+ <button @click="addTodo()">Add</button>
128
+ </div>
129
+
130
+ <ul>
131
+ <li b-for="todo in todos">
132
+ <input type="checkbox" b-sync="todo.done">
133
+ <span class="{{ todo.done ? 'done' : '' }}">
134
+ {{ todo.text }}
135
+ </span>
136
+ </li>
137
+ </ul>
138
+
139
+ <p>{{ remaining() }} remaining</p>
140
+ </template>
141
+
142
+ <script src="https://unpkg.com/lego-dom/main.js"></script>
143
+
144
+ <script>
145
+ // Initialize with data
146
+ Lego.define('todo-app', Lego.registry['todo-app'].innerHTML, {
147
+ newTodo: '',
148
+ todos: [
149
+ { text: 'Learn Lego', done: true },
150
+ { text: 'Build something awesome', done: false }
151
+ ],
152
+ addTodo() {
153
+ if (this.newTodo.trim()) {
154
+ this.todos.push({
155
+ text: this.newTodo,
156
+ done: false
157
+ });
158
+ this.newTodo = '';
159
+ }
160
+ },
161
+ remaining() {
162
+ return this.todos.filter(t => !t.done).length;
163
+ }
164
+ });
165
+ </script>
166
+ </body>
167
+ </html>
168
+ ```
169
+
170
+ ## Progressive Enhancement
171
+
172
+ Lego is perfect for progressively enhancing existing sites:
173
+
174
+ ```html
175
+ <!-- Your existing page -->
176
+ <div id="legacy-content">
177
+ <h1>My Existing Site</h1>
178
+ <p>This works without JavaScript</p>
179
+ </div>
180
+
181
+ <!-- Add interactive components -->
182
+ <user-widget></user-widget>
183
+
184
+ <template b-id="user-widget">
185
+ <style>
186
+ self {
187
+ position: fixed;
188
+ bottom: 1rem;
189
+ right: 1rem;
190
+ background: white;
191
+ padding: 1rem;
192
+ box-shadow: 0 2px 10px rgba(0,0,0,0.1);
193
+ }
194
+ </style>
195
+ <p>Welcome, {{ username }}!</p>
196
+ <button @click="logout()">Logout</button>
197
+ </template>
198
+
199
+ <script src="https://unpkg.com/lego-dom/main.js"></script>
200
+ <script>
201
+ Lego.define('user-widget', Lego.registry['user-widget'].innerHTML, {
202
+ username: 'Guest',
203
+ async mounted() {
204
+ const user = await fetch('/api/user').then(r => r.json());
205
+ this.username = user.name;
206
+ },
207
+ logout() {
208
+ window.location.href = '/logout';
209
+ }
210
+ });
211
+ </script>
212
+ ```
213
+
214
+ ## Embedding in Existing Apps
215
+
216
+ Lego components work alongside other frameworks:
217
+
218
+ ```html
219
+ <!-- Works fine with jQuery, Bootstrap, etc. -->
220
+ <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
221
+ <script src="https://unpkg.com/lego-dom/main.js"></script>
222
+
223
+ <!-- Your Lego component -->
224
+ <my-component></my-component>
225
+
226
+ <!-- Your jQuery code -->
227
+ <script>
228
+ $(document).ready(function() {
229
+ // jQuery code here
230
+ });
231
+ </script>
232
+ ```
233
+
234
+ ## Loading Strategy
235
+
236
+ ### For Production
237
+
238
+ Always pin to a specific version:
239
+
240
+ ```html
241
+ <script src="https://unpkg.com/lego-dom@0.0.7/main.js"></script>
242
+ ```
243
+
244
+ ### For Development/Prototyping
245
+
246
+ Use latest:
247
+
248
+ ```html
249
+ <script src="https://unpkg.com/lego-dom/main.js"></script>
250
+ ```
251
+
252
+ ### With defer
253
+
254
+ Load asynchronously without blocking page render:
255
+
256
+ ```html
257
+ <script defer src="https://unpkg.com/lego-dom/main.js"></script>
258
+ ```
259
+
260
+ ### With integrity (SRI)
261
+
262
+ For maximum security:
263
+
264
+ ```html
265
+ <script
266
+ src="https://unpkg.com/lego-dom@0.0.7/main.js"
267
+ integrity="sha384-..."
268
+ crossorigin="anonymous">
269
+ </script>
270
+ ```
271
+
272
+ ## Browser Compatibility
273
+
274
+ Lego works in all modern browsers:
275
+
276
+ - ✅ Chrome 63+
277
+ - ✅ Firefox 63+
278
+ - ✅ Safari 11.1+
279
+ - ✅ Edge 79+
280
+
281
+ No polyfills needed for these browsers!
282
+
283
+ ## Pros and Cons
284
+
285
+ ### ✅ Advantages
286
+
287
+ - **No build step** - Instant development
288
+ - **No npm** - No dependency management
289
+ - **Fast prototyping** - Perfect for demos and learning
290
+ - **Progressive enhancement** - Add to existing sites easily
291
+ - **Low barrier** - Great for beginners
292
+
293
+ ### ⚠️ Limitations
294
+
295
+ - No tree-shaking (you get the whole library)
296
+ - No TypeScript compilation
297
+ - No `.lego` SFC support
298
+ - No hot module replacement
299
+ - Slower for large apps compared to bundled versions
300
+
301
+ ## When to Use CDN
302
+
303
+ **Perfect for:**
304
+ - Prototypes and demos
305
+ - Small websites (1-5 components)
306
+ - Progressive enhancement
307
+ - Learning and experimentation
308
+ - CodePen/JSFiddle examples
309
+
310
+ **Consider bundling for:**
311
+ - Large applications (10+ components)
312
+ - Production apps requiring optimization
313
+ - Projects needing TypeScript
314
+ - Teams wanting SFC workflow
315
+
316
+ ## Next Steps
317
+
318
+ - See [complete CDN examples](/examples/)
319
+ - Learn about [routing](/guide/routing) for multi-page apps
320
+ - Explore [directives](/guide/directives) for common patterns