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,48 +0,0 @@
1
- # Mama "We Made It!"
2
- Everything we’ve discussed i.e. the Scanner, the Registry, the Router, and the Snap etc. "Everything" stays dormant until `Lego.init()` is called. This function is not just a starter; it’s an orchestrator that synchronizes the JavaScript environment with the existing HTML on the page.
3
-
4
- ## The Lego Initializer
5
-
6
- The code for `init()` is deceptively small because its primary job is to flip the switches on the systems we've already built.
7
-
8
- ### 1. Bootstrapping the Watchdog
9
-
10
- The core of the initialization is setting up the `MutationObserver` we discussed in Topic 7.
11
-
12
- - **The Target**: It targets `document.body`.
13
-
14
- - **The Configuration**: It uses `{ childList: true, subtree: true }`.
15
-
16
- - **The Why**: By starting the observer _before_ the first render, the library ensures that any elements it creates during the initial startup are also caught and "snapped" into life.
17
-
18
-
19
- ### 3. The "Initial Snap" (The Recursive Wake-up)
20
-
21
- Once the observer is live, the code calls `snap(document.body)`.
22
-
23
- - **The Why**: The `MutationObserver` only sees _new_ changes. It cannot see the HTML that was already there when the page loaded.
24
-
25
- - **The Logic**: By manually calling `snap` on the body, the library recursively walks through your entire server-rendered HTML. It finds every custom tag (e.g., `<user-card>`) and "upgrades" them into components.
26
-
27
-
28
- ### 4. Activating the Global Listener
29
-
30
- This is where the **Router Hijack** (Topic 17) is installed.
31
-
32
- - The code adds a single click listener to the `window`.
33
-
34
- - **The Why**: Instead of attaching listeners to every individual `<a>` tag (which would be slow and break when new links are added), it uses **Event Delegation**. It waits for clicks to bubble up to the window, checks if they are `b-link` clicks, and then decides whether to trigger the router.
35
-
36
-
37
- ### 5. The First Route Check
38
-
39
- Finally, `init()` calls `router()` manually for the first time.
40
-
41
- - **The Why**: If a user navigates directly to `mysite.com/dashboard`, the browser loads the page, but the JavaScript needs to know which component to put into the `router-view` immediately. This manual call ensures the UI matches the URL on the very first frame.
42
-
43
-
44
- ----------
45
-
46
- **The Architecture "Why"**: Lego is designed to be **Zero-Config**. By putting all these steps into `init()`, the developer only has to care about one thing: "When is my DOM ready?" The code handles the complex timing of making sure the Watchdog is looking while the Router is switching and the Snap is initializing.
47
-
48
- **Summary**: `Lego.init()` is the bridge. It turns a static document into a reactive application by starting the observer, snapping the existing HTML, and hijacking the navigation.
@@ -1,24 +0,0 @@
1
- # Architectural Deep Dive
2
-
3
- Welcome to the internal documentation of LegoDOM.
4
-
5
- This isn't a "how to use" guide. This is a **"how it works"** guide. I believe that understanding the soul of LegoDOM should/could make you a better contributor.
6
-
7
- ## The Philosophy
8
- **"The Platform is the Runtime."**
9
- We avoid compilers, transpilers, and VDOMs. We use:
10
- - **Proxies** for state.
11
- - **TreeWalkers** for scanning.
12
- - **Regex** for parsing.
13
- - **MutationObservers** for efficiency.
14
-
15
- ## The Journey
16
- Follow the path of a component from HTML string to Pixel:
17
-
18
- 1. [**Init**](./06-init) - How the library wakes up.
19
- 2. [**Scanner**](./11-scanner) - How we find holes in your HTML (Regex vs AST).
20
- 3. [**Studs**](./10-studs) - The Reactivity Engine (Proxies).
21
- 4. [**Render**](./12-render) - The "Loop of Truth" & Security.
22
- 5. [**Router**](./15-router) - The "Surgical" Update philosophy.
23
-
24
- Dive in.
@@ -1,42 +0,0 @@
1
- # Form Example
2
-
3
- Handling forms in Lego.
4
-
5
- ## Live Demo
6
-
7
- ```html
8
- <template b-id="login-form">
9
- <form @submit.prevent="login()">
10
- <div>
11
- <label>Email:</label>
12
- <input type="email" b-sync="email">
13
- </div>
14
-
15
- <div>
16
- <label>Password:</label>
17
- <input type="password" b-sync="password">
18
- </div>
19
-
20
- <p b-show="error" style="color: red">[[ error ]]</p>
21
-
22
- <button type="submit">Login</button>
23
- </form>
24
- </template>
25
-
26
- <script>
27
- Lego.define('login-form', {
28
- email: '',
29
- password: '',
30
- error: '',
31
-
32
- login() {
33
- if (!this.email || !this.password) {
34
- this.error = 'Please fill in all fields';
35
- return;
36
- }
37
- alert(`Logging in as ${this.email}`);
38
- this.error = '';
39
- }
40
- });
41
- </script>
42
- ```
@@ -1,104 +0,0 @@
1
- # Examples
2
-
3
- Explore these hands-on examples to learn Lego patterns and best practices.
4
-
5
- ## Quick Examples
6
-
7
- ### Counter
8
-
9
- A simple reactive counter demonstrating basic state and events.
10
-
11
- ```html
12
- <template b-id="click-counter">
13
- <style>
14
- button { font-size: 1.2rem; padding: 0.5rem 1rem; }
15
- </style>
16
- <p>Count: [[ count ]]</p>
17
- <button @click="count++">Increment</button>
18
- </template>
19
-
20
- <click-counter b-data="{ count: 0 }"></click-counter>
21
- ```
22
-
23
- ### Input Binding
24
-
25
- Two-way data binding with `b-sync`.
26
-
27
- ```html
28
- <template b-id="name-input">
29
- <input b-sync="name" placeholder="Enter your name">
30
- <p b-show="name">Hello, [[ name ]]!</p>
31
- </template>
32
-
33
- <name-input b-data="{ name: '' }"></name-input>
34
- ```
35
-
36
- ### Todo List
37
-
38
- Lists with `b-for`.
39
-
40
- ```html
41
- <template b-id="todo-list">
42
- <ul>
43
- <li b-for="todo in todos">
44
- <input type="checkbox" b-sync="todo.done">
45
- <span class="[[ todo.done ? 'done' : '' ]]">[[ todo.text ]]</span>
46
- </li>
47
- </ul>
48
- </template>
49
-
50
- <todo-list b-data="{
51
- todos: [
52
- { text: 'Learn Lego', done: true },
53
- { text: 'Build an app', done: false }
54
- ]
55
- }"></todo-list>
56
- ```
57
-
58
- ## Full Applications
59
-
60
- ### [Todo App](/examples/todo-app)
61
-
62
- A complete todo application with:
63
- - Add/remove todos
64
- - Mark as complete
65
- - Filter by status
66
- - Local storage persistence
67
-
68
- ### [Routing Demo](/examples/routing)
69
-
70
- Single-page application with:
71
- - Multiple pages
72
- - Dynamic routes
73
- - Navigation
74
- - Route parameters
75
-
76
- ### [SFC Showcase](/examples/sfc-showcase)
77
-
78
- Using Single File Components:
79
- - User cards
80
- - Product grid
81
- - Modal dialogs
82
- - Form validation
83
-
84
- ### [Form Validation](/examples/form)
85
-
86
- Advanced form handling:
87
- - Input validation
88
- - Error messages
89
- - Submit handling
90
- - Reset functionality
91
-
92
- ## CodePen Examples
93
-
94
- Try these examples directly in your browser:
95
-
96
- - [Simple Counter](https://codepen.io/ortserga/pen/XJKdMJm)
97
- - [Todo App](https://codepen.io/ortserga/pen/todo)
98
- - [Dynamic Form](https://codepen.io/ortserga/pen/form)
99
-
100
- ## Next Steps
101
-
102
- - Check the [API Reference](/api/)
103
- - Read the [Guide](/guide/)
104
- - View the [source code](https://github.com/rayattack/Lego)
@@ -1,409 +0,0 @@
1
- # Routing Example
2
-
3
- A multi-page application demonstrating client-side routing.
4
-
5
- ## Full Source Code
6
-
7
- ```html
8
- <!DOCTYPE html>
9
- <html lang="en">
10
- <head>
11
- <meta charset="UTF-8">
12
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
13
- <title>Routing Demo - Lego</title>
14
- <style>
15
- body {
16
- font-family: system-ui, sans-serif;
17
- margin: 0;
18
- padding: 0;
19
- }
20
-
21
- nav {
22
- background: #333;
23
- padding: 1rem;
24
- display: flex;
25
- gap: 1rem;
26
- }
27
-
28
- nav a {
29
- color: white;
30
- text-decoration: none;
31
- padding: 0.5rem 1rem;
32
- border-radius: 4px;
33
- transition: background 0.2s;
34
- }
35
-
36
- nav a:hover {
37
- background: #555;
38
- }
39
-
40
- nav a.active {
41
- background: #4CAF50;
42
- }
43
-
44
- main {
45
- padding: 2rem;
46
- max-width: 800px;
47
- margin: 0 auto;
48
- }
49
- </style>
50
- </head>
51
- <body>
52
- <nav>
53
- <a href="/" b-link>Home</a>
54
- <a href="/about" b-link>About</a>
55
- <a href="/users" b-link>Users</a>
56
- <a href="/contact" b-link>Contact</a>
57
- </nav>
58
-
59
- <main>
60
- <lego-router></lego-router>
61
- </main>
62
-
63
- <script src="https://unpkg.com/lego-dom/main.js"></script>
64
-
65
- <!-- Home Page -->
66
- <template b-id="home-page">
67
- <style>
68
- self { display: block; }
69
- .hero {
70
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
71
- color: white;
72
- padding: 3rem;
73
- border-radius: 8px;
74
- text-align: center;
75
- }
76
- .features {
77
- display: grid;
78
- grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
79
- gap: 1rem;
80
- margin-top: 2rem;
81
- }
82
- .feature {
83
- padding: 1.5rem;
84
- background: #f5f5f5;
85
- border-radius: 8px;
86
- }
87
- </style>
88
-
89
- <div class="hero">
90
- <h1>Welcome to Lego Routing Demo</h1>
91
- <p>Navigate between pages using client-side routing</p>
92
- </div>
93
-
94
- <div class="features">
95
- <div class="feature">
96
- <h3>🚀 Fast</h3>
97
- <p>No page reloads, instant navigation</p>
98
- </div>
99
- <div class="feature">
100
- <h3>📦 Simple</h3>
101
- <p>Built-in router, no dependencies</p>
102
- </div>
103
- <div class="feature">
104
- <h3>🎨 Clean URLs</h3>
105
- <p>No hash-based routing, real paths</p>
106
- </div>
107
- </div>
108
- </template>
109
-
110
- <!-- About Page -->
111
- <template b-id="about-page">
112
- <style>
113
- self { display: block; }
114
- </style>
115
-
116
- <h1>About Lego</h1>
117
- <p>Lego is a tiny, zero-dependency JavaScript library for building reactive Web Components.</p>
118
-
119
- <h2>Features</h2>
120
- <ul>
121
- <li>Zero dependencies</li>
122
- <li>Under 500 lines of code</li>
123
- <li>True reactivity with Proxies</li>
124
- <li>Shadow DOM encapsulation</li>
125
- <li>Built-in routing</li>
126
- </ul>
127
-
128
- <p><a href="/users/1" b-link>View User #1</a></p>
129
- </template>
130
-
131
- <!-- Users List Page -->
132
- <template b-id="users-page">
133
- <style>
134
- self { display: block; }
135
- .user-card {
136
- padding: 1rem;
137
- margin: 0.5rem 0;
138
- background: #f9f9f9;
139
- border-radius: 4px;
140
- display: flex;
141
- justify-content: space-between;
142
- align-items: center;
143
- }
144
- .user-card a {
145
- color: #4CAF50;
146
- text-decoration: none;
147
- font-weight: 600;
148
- }
149
- </style>
150
-
151
- <h1>Users</h1>
152
-
153
- <div class="user-card" b-for="user in users">
154
- <div>
155
- <strong>[[ user.name ]]</strong>
156
- <p style="margin:0;color:#666;">[[ user.email ]]</p>
157
- </div>
158
- <a href="/users/[[ user.id ]]" b-link>View Profile →</a>
159
- </div>
160
- </template>
161
-
162
- <!-- User Profile Page (Dynamic Route) -->
163
- <template b-id="user-profile">
164
- <style>
165
- self { display: block; }
166
- .profile {
167
- background: white;
168
- padding: 2rem;
169
- border-radius: 8px;
170
- box-shadow: 0 2px 8px rgba(0,0,0,0.1);
171
- }
172
- .loading {
173
- text-align: center;
174
- padding: 2rem;
175
- color: #666;
176
- }
177
- </style>
178
-
179
- <div b-show="loading" class="loading">
180
- Loading user...
181
- </div>
182
-
183
- <div b-show="!loading && user" class="profile">
184
- <h1>[[ user.name ]]</h1>
185
- <p><strong>Email:</strong> [[ user.email ]]</p>
186
- <p><strong>Phone:</strong> [[ user.phone ]]</p>
187
- <p><strong>Website:</strong> [[ user.website ]]</p>
188
-
189
- <hr>
190
-
191
- <h3>Address</h3>
192
- <p>
193
- [[ user.address.street ]]<br>
194
- [[ user.address.city ]], [[ user.address.zipcode ]]
195
- </p>
196
-
197
- <p><a href="/users" b-link>← Back to users</a></p>
198
- </div>
199
- </template>
200
-
201
- <!-- Contact Page -->
202
- <template b-id="contact-page">
203
- <style>
204
- self { display: block; }
205
- form {
206
- background: white;
207
- padding: 2rem;
208
- border-radius: 8px;
209
- box-shadow: 0 2px 8px rgba(0,0,0,0.1);
210
- }
211
- .form-group {
212
- margin-bottom: 1rem;
213
- }
214
- label {
215
- display: block;
216
- margin-bottom: 0.5rem;
217
- font-weight: 600;
218
- }
219
- input, textarea {
220
- width: 100%;
221
- padding: 0.75rem;
222
- border: 1px solid #ddd;
223
- border-radius: 4px;
224
- font-size: 1rem;
225
- }
226
- button {
227
- background: #4CAF50;
228
- color: white;
229
- padding: 0.75rem 1.5rem;
230
- border: none;
231
- border-radius: 4px;
232
- cursor: pointer;
233
- font-size: 1rem;
234
- }
235
- .success {
236
- background: #d4edda;
237
- color: #155724;
238
- padding: 1rem;
239
- border-radius: 4px;
240
- margin-top: 1rem;
241
- }
242
- </style>
243
-
244
- <h1>Contact Us</h1>
245
-
246
- <form b-show="!submitted" @submit="handleSubmit(event)">
247
- <div class="form-group">
248
- <label>Name</label>
249
- <input b-sync="form.name" required>
250
- </div>
251
-
252
- <div class="form-group">
253
- <label>Email</label>
254
- <input type="email" b-sync="form.email" required>
255
- </div>
256
-
257
- <div class="form-group">
258
- <label>Message</label>
259
- <textarea b-sync="form.message" rows="5" required></textarea>
260
- </div>
261
-
262
- <button type="submit">Send Message</button>
263
- </form>
264
-
265
- <div b-show="submitted" class="success">
266
- <h3>✅ Message Sent!</h3>
267
- <p>Thank you for contacting us, [[ form.name ]]. We'll respond to [[ form.email ]] soon.</p>
268
- <button @click="submitted = false">Send Another</button>
269
- </div>
270
- </template>
271
-
272
- <script>
273
- // Define routes
274
- Lego.route('/', 'home-page');
275
- Lego.route('/about', 'about-page');
276
- Lego.route('/users', 'users-page');
277
- Lego.route('/users/:id', 'user-profile');
278
- Lego.route('/contact', 'contact-page');
279
-
280
- // Users page component
281
- Lego.define('users-page',
282
- document.querySelector('template[b-id="users-page"]').innerHTML, {
283
- users: [],
284
-
285
- async mounted() {
286
- const response = await fetch('https://jsonplaceholder.typicode.com/users');
287
- this.users = await response.json();
288
- }
289
- }
290
- );
291
-
292
- // User profile component (dynamic route)
293
- Lego.define('user-profile',
294
- document.querySelector('template[b-id="user-profile"]').innerHTML, {
295
- loading: true,
296
- user: null,
297
-
298
- async mounted() {
299
- const userId = Lego.globals.params.id;
300
- const response = await fetch(`https://jsonplaceholder.typicode.com/users/${userId}`);
301
- this.user = await response.json();
302
- this.loading = false;
303
- }
304
- }
305
- );
306
-
307
- // Contact page component
308
- Lego.define('contact-page',
309
- document.querySelector('template[b-id="contact-page"]').innerHTML, {
310
- form: {
311
- name: '',
312
- email: '',
313
- message: ''
314
- },
315
- submitted: false,
316
-
317
- handleSubmit(event) {
318
- event.preventDefault();
319
- this.submitted = true;
320
- }
321
- }
322
- );
323
-
324
- // Update active nav link on route change
325
- window.addEventListener('popstate', updateActiveLink);
326
- updateActiveLink();
327
-
328
- function updateActiveLink() {
329
- document.querySelectorAll('nav a[b-link]').forEach(link => {
330
- const isActive = link.getAttribute('href') === window.location.pathname;
331
- link.classList.toggle('active', isActive);
332
- });
333
- }
334
- </script>
335
- </body>
336
- </html>
337
- ```
338
-
339
- ## Features Demonstrated
340
-
341
- ### ✅ Multiple Routes
342
- - `/` - Home page
343
- - `/about` - About page
344
- - `/users` - Users list
345
- - `/users/:id` - Dynamic user profile
346
- - `/contact` - Contact form
347
-
348
- ### ✅ Dynamic Routes
349
- Access parameters via `Lego.globals.params`:
350
-
351
- ```js
352
- const userId = Lego.globals.params.id;
353
- ```
354
-
355
- ### ✅ Data Fetching
356
- Fetch data in `mounted()` hook:
357
-
358
- ```js
359
- async mounted() {
360
- const response = await fetch('https://api.example.com/users');
361
- this.users = await response.json();
362
- }
363
- ```
364
-
365
- ### ✅ Active Link Styling
366
- Highlight current page in navigation.
367
-
368
- ### ✅ Loading States
369
- Show spinner while fetching data.
370
-
371
- ## Key Concepts
372
-
373
- ### Route Definition
374
-
375
- ```js
376
- Lego.route('/', 'home-page');
377
- Lego.route('/users/:id', 'user-profile');
378
- ```
379
-
380
- ### Accessing Route Params
381
-
382
- ```js
383
- {
384
- mounted() {
385
- const userId = Lego.globals.params.id;
386
- this.fetchUser(userId);
387
- }
388
- }
389
- ```
390
-
391
- ### Navigation
392
-
393
- ```html
394
- <a href="/about" b-link>About</a>
395
- ```
396
-
397
- ## Try It Yourself
398
-
399
- 1. Copy the code above
400
- 2. Save as `routing-demo.html`
401
- 3. Open in a browser
402
- 4. Click links—no page reload!
403
- 5. Use browser back/forward buttons
404
-
405
- ## Next Steps
406
-
407
- - See [Todo App Example](/examples/todo-app)
408
- - Learn about [Routing Guide](/guide/routing)
409
- - Try [Form Validation Example](/examples/form)
@@ -1,34 +0,0 @@
1
- # SFC Showcase
2
-
3
- Using `.lego` files with Vite.
4
-
5
- ## File Structure
6
-
7
- **Counter.lego**
8
- ```html
9
- <template>
10
- <button @click="count++">Count: [[ count ]]</button>
11
- </template>
12
-
13
- <style>
14
- button { color: red; }
15
- </style>
16
-
17
- <script>
18
- export default {
19
- count: 0
20
- }
21
- </script>
22
- ```
23
-
24
- ## Usage
25
-
26
- **main.js**
27
- ```js
28
- import './Counter.lego';
29
- ```
30
-
31
- **index.html**
32
- ```html
33
- <counter-component></counter-component>
34
- ```