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,383 +0,0 @@
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-show="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)