lego-dom 0.0.7 → 0.0.8

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 (143) hide show
  1. package/.github/workflows/deploy-docs.yml +56 -0
  2. package/LICENSE +21 -0
  3. package/README.md +122 -0
  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.DOjt7AV0.js +3 -0
  18. package/docs/.vitepress/dist/assets/api_globals.md.DOjt7AV0.lean.js +1 -0
  19. package/docs/.vitepress/dist/assets/api_index.md.OS6h01ct.js +1 -0
  20. package/docs/.vitepress/dist/assets/api_index.md.OS6h01ct.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.DNn9VhL5.js +13 -0
  26. package/docs/.vitepress/dist/assets/api_vite-plugin.md.DNn9VhL5.lean.js +1 -0
  27. package/docs/.vitepress/dist/assets/app.BG5s3B0P.js +1 -0
  28. package/docs/.vitepress/dist/assets/chunks/@localSearchIndexroot.DQmuWC2Z.js +1 -0
  29. package/docs/.vitepress/dist/assets/chunks/VPLocalSearchBox.BO-PSxt1.js +9 -0
  30. package/docs/.vitepress/dist/assets/chunks/framework.B7OFBR9X.js +19 -0
  31. package/docs/.vitepress/dist/assets/chunks/theme.DA-iSa9B.js +2 -0
  32. package/docs/.vitepress/dist/assets/examples_form.md.B3stGKbu.js +34 -0
  33. package/docs/.vitepress/dist/assets/examples_form.md.B3stGKbu.lean.js +1 -0
  34. package/docs/.vitepress/dist/assets/examples_index.md.BDEG_D4J.js +30 -0
  35. package/docs/.vitepress/dist/assets/examples_index.md.BDEG_D4J.lean.js +1 -0
  36. package/docs/.vitepress/dist/assets/examples_routing.md.bqZ9DjDK.js +338 -0
  37. package/docs/.vitepress/dist/assets/examples_routing.md.bqZ9DjDK.lean.js +1 -0
  38. package/docs/.vitepress/dist/assets/examples_sfc-showcase.md.DLXaUiop.js +13 -0
  39. package/docs/.vitepress/dist/assets/examples_sfc-showcase.md.DLXaUiop.lean.js +1 -0
  40. package/docs/.vitepress/dist/assets/examples_todo-app.md.D5RhZoo5.js +297 -0
  41. package/docs/.vitepress/dist/assets/examples_todo-app.md.D5RhZoo5.lean.js +1 -0
  42. package/docs/.vitepress/dist/assets/guide_cdn-usage.md.CAjf03Lr.js +182 -0
  43. package/docs/.vitepress/dist/assets/guide_cdn-usage.md.CAjf03Lr.lean.js +1 -0
  44. package/docs/.vitepress/dist/assets/guide_components.md.BIFWF1Hc.js +174 -0
  45. package/docs/.vitepress/dist/assets/guide_components.md.BIFWF1Hc.lean.js +1 -0
  46. package/docs/.vitepress/dist/assets/guide_contributing.md.BgbUN-Mr.js +1 -0
  47. package/docs/.vitepress/dist/assets/guide_contributing.md.BgbUN-Mr.lean.js +1 -0
  48. package/docs/.vitepress/dist/assets/guide_directives.md.Bi3ynu1d.js +140 -0
  49. package/docs/.vitepress/dist/assets/guide_directives.md.Bi3ynu1d.lean.js +1 -0
  50. package/docs/.vitepress/dist/assets/guide_getting-started.md.2Nr1lp2z.js +107 -0
  51. package/docs/.vitepress/dist/assets/guide_getting-started.md.2Nr1lp2z.lean.js +1 -0
  52. package/docs/.vitepress/dist/assets/guide_index.md.GvZq_Yf2.js +2 -0
  53. package/docs/.vitepress/dist/assets/guide_index.md.GvZq_Yf2.lean.js +1 -0
  54. package/docs/.vitepress/dist/assets/guide_lifecycle.md.B28j1OzS.js +304 -0
  55. package/docs/.vitepress/dist/assets/guide_lifecycle.md.B28j1OzS.lean.js +1 -0
  56. package/docs/.vitepress/dist/assets/guide_quick-start.md.CNk3VGTF.js +33 -0
  57. package/docs/.vitepress/dist/assets/guide_quick-start.md.CNk3VGTF.lean.js +1 -0
  58. package/docs/.vitepress/dist/assets/guide_reactivity.md.CVsaMaPv.js +135 -0
  59. package/docs/.vitepress/dist/assets/guide_reactivity.md.CVsaMaPv.lean.js +1 -0
  60. package/docs/.vitepress/dist/assets/guide_routing.md.DSpDP25o.js +193 -0
  61. package/docs/.vitepress/dist/assets/guide_routing.md.DSpDP25o.lean.js +1 -0
  62. package/docs/.vitepress/dist/assets/guide_sfc.md.CVUP66tS.js +187 -0
  63. package/docs/.vitepress/dist/assets/guide_sfc.md.CVUP66tS.lean.js +1 -0
  64. package/docs/.vitepress/dist/assets/guide_templating.md.BgCGe4aa.js +119 -0
  65. package/docs/.vitepress/dist/assets/guide_templating.md.BgCGe4aa.lean.js +1 -0
  66. package/docs/.vitepress/dist/assets/index.md.xV1taCED.js +23 -0
  67. package/docs/.vitepress/dist/assets/index.md.xV1taCED.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 +368 -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 +38 -0
  130. package/examples/vite-app/README.md +71 -0
  131. package/examples/vite-app/index.html +45 -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/main.js +11 -0
  136. package/examples/vite-app/vite.config.js +16 -0
  137. package/examples.js +99 -0
  138. package/package.json +33 -5
  139. package/parse-lego.js +119 -0
  140. package/parse-lego.test.js +107 -0
  141. package/vite-plugin.js +133 -0
  142. package/.ignore/auto.html +0 -135
  143. package/.ignore/test.html +0 -73
@@ -0,0 +1,394 @@
1
+ # Components
2
+
3
+ Learn how to create and use components in LegoJS.
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
+ ```html
10
+ <template b-id="user-badge">
11
+ <style>
12
+ self {
13
+ display: inline-flex;
14
+ align-items: center;
15
+ gap: 0.5rem;
16
+ padding: 0.5rem 1rem;
17
+ background: #f0f0f0;
18
+ border-radius: 20px;
19
+ }
20
+ .avatar {
21
+ width: 32px;
22
+ height: 32px;
23
+ border-radius: 50%;
24
+ }
25
+ </style>
26
+
27
+ <img class="avatar" src="{{ avatarUrl }}" alt="{{ name }}">
28
+ <span>{{ name }}</span>
29
+ </template>
30
+ ```
31
+
32
+ ## Creating Components
33
+
34
+ ### Method 1: HTML Templates
35
+
36
+ Define components directly in your HTML with `<template b-id>`:
37
+
38
+ ```html
39
+ <template b-id="hello-world">
40
+ <h1>Hello {{ name }}!</h1>
41
+ </template>
42
+
43
+ <hello-world b-data="{ name: 'Alice' }"></hello-world>
44
+ ```
45
+
46
+ ### Method 2: JavaScript
47
+
48
+ Use `Lego.define()` for programmatic component creation:
49
+
50
+ ```js
51
+ Lego.define('hello-world', `
52
+ <h1>Hello {{ name }}!</h1>
53
+ `, {
54
+ name: 'Alice'
55
+ });
56
+ ```
57
+
58
+ ### Method 3: Single File Components (.lego)
59
+
60
+ With Vite, use `.lego` files:
61
+
62
+ ```html
63
+ <!-- hello-world.lego -->
64
+ <template>
65
+ <h1>Hello {{ name }}!</h1>
66
+ </template>
67
+
68
+ <script>
69
+ export default {
70
+ name: 'Alice'
71
+ }
72
+ </script>
73
+ ```
74
+
75
+ ## Component State
76
+
77
+ State is defined in the component's logic object:
78
+
79
+ ```js
80
+ {
81
+ // Data properties
82
+ count: 0,
83
+ username: 'Alice',
84
+ items: ['apple', 'banana'],
85
+
86
+ // Methods
87
+ increment() {
88
+ this.count++;
89
+ },
90
+
91
+ addItem(item) {
92
+ this.items.push(item);
93
+ }
94
+ }
95
+ ```
96
+
97
+ Access state in templates using `{{ }}`:
98
+
99
+ ```html
100
+ <p>Count: {{ count }}</p>
101
+ <button @click="increment()">+1</button>
102
+ ```
103
+
104
+ ## Passing Data
105
+
106
+ ### Via b-data Attribute
107
+
108
+ ```html
109
+ <user-card b-data="{
110
+ name: 'Bob',
111
+ email: 'bob@example.com',
112
+ role: 'admin'
113
+ }"></user-card>
114
+ ```
115
+
116
+ ### Merging with Defaults
117
+
118
+ Component defaults are merged with `b-data`:
119
+
120
+ ```js
121
+ Lego.define('user-card', `...`, {
122
+ name: 'Guest', // Default
123
+ email: '', // Default
124
+ role: 'user' // Default
125
+ });
126
+ ```
127
+
128
+ ```html
129
+ <!-- Only name is overridden -->
130
+ <user-card b-data="{ name: 'Alice' }"></user-card>
131
+ <!-- email and role use defaults -->
132
+ ```
133
+
134
+ ## Component Communication
135
+
136
+ ### Parent → Child (Props)
137
+
138
+ Pass data via `b-data`:
139
+
140
+ ```html
141
+ <child-component b-data="{ title: parentData.title }"></child-component>
142
+ ```
143
+
144
+ ### Child → Parent (Events)
145
+
146
+ Use `$emit()` to dispatch custom events:
147
+
148
+ ```html
149
+ <!-- Child component -->
150
+ <button @click="$emit('save', { id: 123 })">Save</button>
151
+ ```
152
+
153
+ ```js
154
+ // Parent listens
155
+ document.querySelector('child-component')
156
+ .addEventListener('save', (e) => {
157
+ console.log('Saved:', e.detail); // { id: 123 }
158
+ });
159
+ ```
160
+
161
+ ### Accessing Ancestors
162
+
163
+ Use `$ancestors()` to read parent component state:
164
+
165
+ ```html
166
+ <!-- In nested component -->
167
+ <p>App title: {{ $ancestors('app-root').title }}</p>
168
+ ```
169
+
170
+ ::: warning Read-Only
171
+ `$ancestors()` is for reading parent state, not mutating it.
172
+ :::
173
+
174
+ ## Component Composition
175
+
176
+ ### Nesting Components
177
+
178
+ ```html
179
+ <template b-id="app-layout">
180
+ <header>
181
+ <app-header></app-header>
182
+ </header>
183
+ <main>
184
+ <app-sidebar></app-sidebar>
185
+ <app-content></app-content>
186
+ </main>
187
+ </template>
188
+ ```
189
+
190
+ ### Using Slots
191
+
192
+ Standard Web Components slots work:
193
+
194
+ ```html
195
+ <template b-id="card-container">
196
+ <div class="card">
197
+ <slot name="header"></slot>
198
+ <slot></slot>
199
+ <slot name="footer"></slot>
200
+ </div>
201
+ </template>
202
+
203
+ <!-- Usage -->
204
+ <card-container>
205
+ <h2 slot="header">Title</h2>
206
+ <p>Main content</p>
207
+ <button slot="footer">Action</button>
208
+ </card-container>
209
+ ```
210
+
211
+ ## Shadow DOM
212
+
213
+ All components use Shadow DOM for style encapsulation.
214
+
215
+ ### Benefits
216
+
217
+ ✅ **Scoped Styles** - CSS doesn't leak in or out
218
+ ✅ **No Naming Conflicts** - ID/class names are isolated
219
+ ✅ **Composability** - Components work without side effects
220
+
221
+ ### Styling the Host
222
+
223
+ Use `self` keyword (converts to `:host`):
224
+
225
+ ```html
226
+ <style>
227
+ self {
228
+ display: block;
229
+ padding: 1rem;
230
+ }
231
+
232
+ self:hover {
233
+ background: #f5f5f5;
234
+ }
235
+ </style>
236
+ ```
237
+
238
+ ## Lifecycle
239
+
240
+ Components have three lifecycle hooks:
241
+
242
+ ```js
243
+ {
244
+ mounted() {
245
+ // Component added to DOM
246
+ this.fetchData();
247
+ },
248
+
249
+ updated() {
250
+ // State changed and re-rendered
251
+ console.log('New count:', this.count);
252
+ },
253
+
254
+ unmounted() {
255
+ // Component removed from DOM
256
+ clearInterval(this.timer);
257
+ }
258
+ }
259
+ ```
260
+
261
+ See [Lifecycle Hooks](/guide/lifecycle) for details.
262
+
263
+ ## Best Practices
264
+
265
+ ### 1. Keep Components Small
266
+
267
+ Each component should have a single responsibility.
268
+
269
+ ✅ Good: `user-avatar`, `user-name`, `user-bio`
270
+ ❌ Bad: `entire-user-profile-page`
271
+
272
+ ### 2. Use Semantic Names
273
+
274
+ Name components after what they represent:
275
+
276
+ ✅ Good: `product-card`, `search-bar`
277
+ ❌ Bad: `blue-box`, `flex-container`
278
+
279
+ ### 3. Avoid Deep Nesting
280
+
281
+ Keep component trees shallow (3-4 levels max):
282
+
283
+ ```html
284
+ app-root
285
+ ├── app-header
286
+ │ └── nav-menu
287
+ ├── app-main
288
+ │ └── content-area
289
+ └── app-footer
290
+ ```
291
+
292
+ ### 4. Initialize State in mounted()
293
+
294
+ Fetch data or set up timers in `mounted()`:
295
+
296
+ ```js
297
+ {
298
+ data: null,
299
+ mounted() {
300
+ this.fetchData();
301
+ },
302
+ async fetchData() {
303
+ this.data = await fetch('/api/data').then(r => r.json());
304
+ }
305
+ }
306
+ ```
307
+
308
+ ### 5. Clean Up in unmounted()
309
+
310
+ Clear timers, remove listeners:
311
+
312
+ ```js
313
+ {
314
+ timer: null,
315
+ mounted() {
316
+ this.timer = setInterval(() => this.tick(), 1000);
317
+ },
318
+ unmounted() {
319
+ clearInterval(this.timer);
320
+ }
321
+ }
322
+ ```
323
+
324
+ ## Common Patterns
325
+
326
+ ### Loading States
327
+
328
+ ```html
329
+ <div b-if="loading">Loading...</div>
330
+ <div b-if="!loading && data">
331
+ <h2>{{ data.title }}</h2>
332
+ <p>{{ data.content }}</p>
333
+ </div>
334
+ <div b-if="!loading && error">
335
+ Error: {{ error }}
336
+ </div>
337
+ ```
338
+
339
+ ### Form Components
340
+
341
+ ```js
342
+ {
343
+ form: {
344
+ username: '',
345
+ email: '',
346
+ password: ''
347
+ },
348
+ errors: {},
349
+
350
+ validate() {
351
+ this.errors = {};
352
+ if (!this.form.username) {
353
+ this.errors.username = 'Required';
354
+ }
355
+ if (!this.form.email.includes('@')) {
356
+ this.errors.email = 'Invalid email';
357
+ }
358
+ return Object.keys(this.errors).length === 0;
359
+ },
360
+
361
+ submit() {
362
+ if (this.validate()) {
363
+ // Submit form
364
+ }
365
+ }
366
+ }
367
+ ```
368
+
369
+ ### Computed Values
370
+
371
+ Use methods for computed values:
372
+
373
+ ```js
374
+ {
375
+ items: [
376
+ { name: 'Apple', price: 1.20 },
377
+ { name: 'Banana', price: 0.80 }
378
+ ],
379
+
380
+ total() {
381
+ return this.items.reduce((sum, item) => sum + item.price, 0);
382
+ }
383
+ }
384
+ ```
385
+
386
+ ```html
387
+ <p>Total: ${{ total().toFixed(2) }}</p>
388
+ ```
389
+
390
+ ## Next Steps
391
+
392
+ - Learn about [Reactivity](/guide/reactivity) in depth
393
+ - Explore [Templating](/guide/templating) features
394
+ - See [complete examples](/examples/)
@@ -0,0 +1,32 @@
1
+ # Contributing
2
+
3
+ Thank you for your interest in contributing to LegoJS!
4
+
5
+ ## Development Setup
6
+
7
+ 1. Clone the repository:
8
+ ```bash
9
+ git clone https://github.com/rayattack/LegoJS.git
10
+ ```
11
+
12
+ 2. Install dependencies:
13
+ ```bash
14
+ yarn install
15
+ ```
16
+
17
+ 3. Run the dev server for docs:
18
+ ```bash
19
+ yarn docs:dev
20
+ ```
21
+
22
+ ## Pull Requests
23
+
24
+ 1. Fork the repo and create your branch from `main`.
25
+ 2. If you've added code that should be tested, add tests.
26
+ 3. If you've changed APIs, update the documentation.
27
+ 4. Ensure the test suite passes.
28
+ 5. Make sure your code lints.
29
+
30
+ ## License
31
+
32
+ By contributing, you agree that your contributions will be licensed under its MIT License.