ladrillosjs 1.0.0-rc.8 → 1.0.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.
- package/README.md +399 -101
- package/dist/core/main.d.ts +31 -0
- package/dist/core/store.d.ts +6 -0
- package/dist/core/webcomponent.d.ts +2 -0
- package/dist/index-CYYvcgtW.mjs +215 -0
- package/dist/index-D8qqeJcR.js +3 -0
- package/dist/index.d.ts +10 -0
- package/dist/ladrillosjs.cjs.js +1 -1
- package/dist/ladrillosjs.es.js +4 -2
- package/dist/ladrillosjs.umd.js +18 -3
- package/dist/types/LadrilloTypes.d.ts +18 -0
- package/dist/utils/logger.d.ts +20 -0
- package/dist/utils/stringify.d.ts +7 -0
- package/dist/webcomponent-8TKKZviJ.mjs +708 -0
- package/dist/webcomponent-BOcL3Sbk.js +16 -0
- package/package.json +45 -37
- package/dist/index-IQGQBTGZ.mjs +0 -145
- package/dist/index-zVbhe3gY.js +0 -3
- package/dist/webcomponent-CQbzaQn7.mjs +0 -326
- package/dist/webcomponent-DtOxd5O6.js +0 -1
package/README.md
CHANGED
|
@@ -6,168 +6,466 @@ A lightweight, zero-dependency web component framework for building modular web
|
|
|
6
6
|
|
|
7
7
|
"I designed this framework to empower developers with the ability to componentize their code efficiently and effectively, without the need for a full-scale framework. By focusing on simplicity and leveraging core web fundamentals, my goal was to create a lightweight and accessible solution that enhances development while staying true to the basics."
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## Table of Contents
|
|
10
|
+
|
|
11
|
+
- [Features](#features)
|
|
12
|
+
- [Getting Started](#getting-started)
|
|
13
|
+
- [Installation](#installation)
|
|
14
|
+
- [Your First Component](#your-first-component)
|
|
15
|
+
- [Core Concepts](#core-concepts)
|
|
16
|
+
- [Component Registration](#component-registration)
|
|
17
|
+
- [State Management](#state-management)
|
|
18
|
+
- [Event Handling](#event-handling)
|
|
19
|
+
- [Data Binding](#data-binding)
|
|
20
|
+
- [Conditional Rendering](#conditional-rendering)
|
|
21
|
+
- [Slots](#slots)
|
|
22
|
+
- [Advanced Features](#advanced-features)
|
|
23
|
+
- [External Scripts](#external-scripts)
|
|
24
|
+
- [Global State Stores](#global-state-stores)
|
|
25
|
+
- [Shadow DOM](#shadow-dom)
|
|
26
|
+
- [API Reference](#api-reference)
|
|
27
|
+
- [Examples](#examples)
|
|
28
|
+
- [Contributing](#contributing)
|
|
29
|
+
- [License](#license)
|
|
30
|
+
|
|
31
|
+
## Features
|
|
32
|
+
|
|
33
|
+
- 🚀 **Zero Dependencies** - Pure JavaScript, no build tools required
|
|
34
|
+
- 📦 **Single-File Components** - HTML, CSS, and JavaScript in one file
|
|
35
|
+
- ⚡ **Reactive State** - Automatic re-rendering on state changes
|
|
36
|
+
- 🎯 **Event System** - Built-in event emission and listening
|
|
37
|
+
- 🔄 **Two-Way Data Binding** - For form inputs and contenteditable elements
|
|
38
|
+
- 🎨 **Scoped Styles** - Component styles with optional Shadow DOM
|
|
39
|
+
- 🏪 **State Management** - Simple store implementation for shared state
|
|
40
|
+
- 🔌 **Slots Support** - Content projection with named and default slots
|
|
41
|
+
- 📝 **TypeScript Support** - Includes type definitions
|
|
42
|
+
|
|
43
|
+
## Getting Started
|
|
44
|
+
|
|
45
|
+
The repository includes several example applications that demonstrate various features:
|
|
46
|
+
|
|
47
|
+
- **[Todo App](samples/apps/todo)** - Classic todo list with component composition
|
|
48
|
+
- **[Notes App](samples/apps/notes)** - Multi-component app with global state management
|
|
49
|
+
- **[Markdown Editor](samples/apps/markdown)** - Real-time markdown preview
|
|
50
|
+
- **[API Example](samples/apps/api)** - Fetching and displaying external data
|
|
51
|
+
- **[Business Card](samples/apps/biz)** - Editable form with two-way data binding
|
|
52
|
+
- **[Button Game](samples/apps/button-game)** - Interactive game with component events
|
|
53
|
+
- **[Slideshow](samples/apps/slideshow)** - Multi-slide presentation system
|
|
54
|
+
- **[Docs](samples/apps/docs)** - Documentation viewer with syntax highlighting
|
|
55
|
+
|
|
56
|
+
To run the examples:
|
|
10
57
|
|
|
11
|
-
|
|
12
|
-
|
|
58
|
+
```bash
|
|
59
|
+
# Clone the repository
|
|
60
|
+
git clone https://github.com/drubiodev/LadrillosJS.git
|
|
61
|
+
cd LadrillosJS
|
|
62
|
+
|
|
63
|
+
# Install dependencies (for dev server only)
|
|
64
|
+
npm install
|
|
13
65
|
|
|
14
|
-
|
|
66
|
+
# Start the development server
|
|
67
|
+
npm run dev
|
|
68
|
+
```
|
|
15
69
|
|
|
16
|
-
|
|
70
|
+
## Installation
|
|
71
|
+
|
|
72
|
+
### NPM
|
|
17
73
|
|
|
18
74
|
```bash
|
|
19
75
|
npm install ladrillosjs
|
|
20
76
|
```
|
|
21
77
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
### cdn
|
|
78
|
+
### CDN
|
|
25
79
|
|
|
26
|
-
```
|
|
80
|
+
```html
|
|
27
81
|
<script defer src="https://cdn.jsdelivr.net/npm/ladrillosjs"></script>
|
|
28
82
|
```
|
|
29
83
|
|
|
30
|
-
## First Component
|
|
84
|
+
## Your First Component
|
|
31
85
|
|
|
32
|
-
A component in LadrillosJS is a reusable custom HTML element that bundles its own template, logic
|
|
86
|
+
A component in LadrillosJS is a reusable custom HTML element that bundles its own template, logic, and styles into a single file.
|
|
33
87
|
|
|
34
|
-
|
|
88
|
+
### 1. Create a Component File
|
|
35
89
|
|
|
36
|
-
|
|
90
|
+
Create `hello-world.html`:
|
|
37
91
|
|
|
38
|
-
|
|
39
|
-
|
|
92
|
+
```html
|
|
93
|
+
<!-- hello-world.html -->
|
|
94
|
+
<div class="greeting">
|
|
95
|
+
<h1>{title}</h1>
|
|
96
|
+
<p>Hello, {name}!</p>
|
|
97
|
+
<button onclick="greet">Click me ({count})</button>
|
|
98
|
+
</div>
|
|
40
99
|
|
|
41
|
-
|
|
42
|
-
|
|
100
|
+
<script>
|
|
101
|
+
// Component state
|
|
102
|
+
let title = "Welcome to LadrillosJS";
|
|
103
|
+
let name = "World";
|
|
104
|
+
let count = 0;
|
|
105
|
+
|
|
106
|
+
// Event handler
|
|
107
|
+
const greet = () => {
|
|
108
|
+
count++;
|
|
109
|
+
name = prompt("What's your name?") || "World";
|
|
110
|
+
};
|
|
111
|
+
</script>
|
|
43
112
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
113
|
+
<style>
|
|
114
|
+
.greeting {
|
|
115
|
+
text-align: center;
|
|
116
|
+
padding: 2rem;
|
|
117
|
+
background: #f0f0f0;
|
|
118
|
+
border-radius: 8px;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
button {
|
|
122
|
+
padding: 0.5rem 1rem;
|
|
123
|
+
font-size: 1rem;
|
|
124
|
+
cursor: pointer;
|
|
125
|
+
}
|
|
126
|
+
</style>
|
|
127
|
+
```
|
|
47
128
|
|
|
48
|
-
|
|
49
|
-
const increment = () => {
|
|
50
|
-
count++;
|
|
51
|
-
// update component state and re-render
|
|
52
|
-
this.setState({ count });
|
|
53
|
-
};
|
|
54
|
-
</script>
|
|
129
|
+
### 2. Register and Use the Component
|
|
55
130
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
131
|
+
```html
|
|
132
|
+
<!DOCTYPE html>
|
|
133
|
+
<html>
|
|
134
|
+
<head>
|
|
135
|
+
<title>My App</title>
|
|
136
|
+
</head>
|
|
137
|
+
<body>
|
|
138
|
+
<!-- Use your component -->
|
|
139
|
+
<hello-world></hello-world>
|
|
140
|
+
|
|
141
|
+
<!-- Register component -->
|
|
142
|
+
<script type="module">
|
|
143
|
+
import { registerComponent } from "ladrillosjs";
|
|
144
|
+
registerComponent("hello-world", "./hello-world.html");
|
|
145
|
+
</script>
|
|
146
|
+
</body>
|
|
147
|
+
</html>
|
|
148
|
+
```
|
|
68
149
|
|
|
69
|
-
|
|
150
|
+
## Core Concepts
|
|
70
151
|
|
|
71
|
-
|
|
72
|
-
<!-- import -->
|
|
73
|
-
<script type="module">
|
|
74
|
-
import { registerComponent } from "ladrillosjs";
|
|
152
|
+
### Component Registration
|
|
75
153
|
|
|
76
|
-
|
|
77
|
-
</script>
|
|
154
|
+
Register single or multiple components:
|
|
78
155
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
```
|
|
156
|
+
```javascript
|
|
157
|
+
// Single component
|
|
158
|
+
import { registerComponent } from "ladrillosjs";
|
|
159
|
+
registerComponent("my-component", "./my-component.html");
|
|
84
160
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
161
|
+
// Multiple components with concurrency control
|
|
162
|
+
import { registerComponents } from "ladrillosjs";
|
|
163
|
+
await registerComponents(
|
|
164
|
+
[
|
|
165
|
+
{ name: "app-header", path: "./components/header.html" },
|
|
166
|
+
{ name: "app-footer", path: "./components/footer.html" },
|
|
167
|
+
{ name: "user-card", path: "./components/user-card.html" },
|
|
168
|
+
],
|
|
169
|
+
10
|
|
170
|
+
); // Max 10 parallel fetches (default: 5)
|
|
89
171
|
|
|
90
|
-
|
|
172
|
+
// Using CDN
|
|
173
|
+
ladrillosjs.registerComponent("my-component", "./my-component.html");
|
|
174
|
+
```
|
|
91
175
|
|
|
92
|
-
|
|
93
|
-
- Top‐level `let/const/function` in your `<script>` block are hoisted and initialized into `this.state` if they appear in a template or event.
|
|
94
|
-
- Event attributes like `onclick="increment"` register listeners under the hood.
|
|
176
|
+
### State Management
|
|
95
177
|
|
|
96
|
-
|
|
178
|
+
Components have reactive state that automatically triggers re-renders:
|
|
97
179
|
|
|
98
|
-
|
|
180
|
+
```html
|
|
181
|
+
<div>
|
|
182
|
+
<h2>User: {user.name}</h2>
|
|
183
|
+
<p>Score: {score}</p>
|
|
184
|
+
<button onclick="updateScore">Add Point</button>
|
|
185
|
+
</div>
|
|
186
|
+
|
|
187
|
+
<script>
|
|
188
|
+
const date = new Date(Date.now());
|
|
189
|
+
const formattedDate = date.toLocaleDateString("en-US"); // Format: MM/DD/YYYY
|
|
190
|
+
// Initial state
|
|
191
|
+
let score = 0;
|
|
192
|
+
let user = {
|
|
193
|
+
name: "Player 1",
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
const updateScore = () => {
|
|
197
|
+
// Update state and trigger re-render
|
|
198
|
+
score++;
|
|
199
|
+
};
|
|
200
|
+
</script>
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Event Handling
|
|
204
|
+
|
|
205
|
+
Multiple ways to handle events:
|
|
99
206
|
|
|
100
207
|
```html
|
|
101
|
-
|
|
208
|
+
<!-- Method reference -->
|
|
209
|
+
<button onclick="handleClick">Click me: {count}</button>
|
|
210
|
+
|
|
211
|
+
<!-- Function with arguments -->
|
|
212
|
+
<button onclick="addItem('Hello', 123)">Add Item</button>
|
|
213
|
+
|
|
214
|
+
<!-- Inline arrow function -->
|
|
215
|
+
<button onclick="(e) => console.log(e.target)">Log Target</button>
|
|
216
|
+
|
|
217
|
+
<script>
|
|
218
|
+
const count = 0;
|
|
219
|
+
this.setState({ items: [] });
|
|
220
|
+
|
|
221
|
+
const handleClick = (event) => {
|
|
222
|
+
console.log("Clicked!", event);
|
|
223
|
+
count++;
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
const addItem = (name, value) => {
|
|
227
|
+
this.setState({ items: [...this.state.items, { name, value }] });
|
|
228
|
+
};
|
|
229
|
+
</script>
|
|
230
|
+
<div>
|
|
231
|
+
<h1>Shopping Cart ({items.length} items)</h1>
|
|
232
|
+
|
|
233
|
+
<div data-if="items.length === 0">
|
|
234
|
+
<p>Your cart is empty</p>
|
|
235
|
+
</div>
|
|
236
|
+
|
|
237
|
+
<div data-else-if="items.length < 3">
|
|
238
|
+
<p>You have a few items</p>
|
|
239
|
+
</div>
|
|
240
|
+
|
|
241
|
+
<div data-else>
|
|
242
|
+
<p>You have many items!</p>
|
|
243
|
+
</div>
|
|
244
|
+
|
|
245
|
+
<button data-if="!isLoggedIn" onclick="login">Login</button>
|
|
246
|
+
<button data-else onclick="logout">Logout</button>
|
|
247
|
+
</div>
|
|
248
|
+
<script>
|
|
249
|
+
const items = ["apple", "banana", "orange"];
|
|
250
|
+
const isLoggedIn = false;
|
|
251
|
+
|
|
252
|
+
function login() {
|
|
253
|
+
isLoggedIn = true;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
function logout() {
|
|
257
|
+
isLoggedIn = false;
|
|
258
|
+
}
|
|
259
|
+
</script>
|
|
102
260
|
```
|
|
103
261
|
|
|
104
|
-
|
|
262
|
+
### Slots
|
|
263
|
+
|
|
264
|
+
Content projection using slots:
|
|
105
265
|
|
|
106
266
|
```html
|
|
107
|
-
|
|
267
|
+
<!-- card.html -->
|
|
268
|
+
<div class="card">
|
|
269
|
+
<div class="card-header">
|
|
270
|
+
<slot name="header">Default Header</slot>
|
|
271
|
+
</div>
|
|
272
|
+
<div class="card-body">
|
|
273
|
+
<slot></slot>
|
|
274
|
+
<!-- Default slot -->
|
|
275
|
+
</div>
|
|
276
|
+
<div class="card-footer">
|
|
277
|
+
<slot name="footer"></slot>
|
|
278
|
+
</div>
|
|
279
|
+
</div>
|
|
280
|
+
|
|
281
|
+
<!-- Usage -->
|
|
282
|
+
<my-card>
|
|
283
|
+
<h2 slot="header">User Profile</h2>
|
|
284
|
+
<p>This goes in the default slot</p>
|
|
285
|
+
<button slot="footer">Save</button>
|
|
286
|
+
</my-card>
|
|
108
287
|
```
|
|
109
288
|
|
|
110
|
-
##
|
|
289
|
+
## Advanced Features
|
|
111
290
|
|
|
112
|
-
|
|
291
|
+
### External Scripts
|
|
113
292
|
|
|
114
|
-
|
|
293
|
+
Load external JavaScript with components:
|
|
115
294
|
|
|
116
|
-
|
|
117
|
-
|
|
295
|
+
```html
|
|
296
|
+
<!-- With 'bind' attribute for component context -->
|
|
297
|
+
<script src="./helpers.js" bind></script>
|
|
298
|
+
|
|
299
|
+
<!-- ES modules with bind -->
|
|
300
|
+
<script src="./component-logic.js" type="module" bind></script>
|
|
118
301
|
|
|
119
|
-
|
|
120
|
-
<script src="
|
|
302
|
+
<!-- Regular external script -->
|
|
303
|
+
<script src="https://cdn.example.com/library.js"></script>
|
|
121
304
|
```
|
|
122
305
|
|
|
123
|
-
|
|
124
|
-
|
|
306
|
+
For modules with `bind`, export a default function:
|
|
307
|
+
|
|
308
|
+
```javascript
|
|
309
|
+
// component-logic.js
|
|
310
|
+
export default function () {
|
|
311
|
+
// 'this' refers to the component instance
|
|
312
|
+
this.formatDate = (date) => {
|
|
313
|
+
return new Intl.DateTimeFormat("en-US").format(date);
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
this.init = () => {
|
|
317
|
+
console.log("Component initialized");
|
|
318
|
+
};
|
|
125
319
|
|
|
126
|
-
|
|
320
|
+
// Called automatically if defined
|
|
321
|
+
this.init();
|
|
322
|
+
}
|
|
323
|
+
```
|
|
127
324
|
|
|
128
|
-
|
|
325
|
+
### Global State Stores
|
|
129
326
|
|
|
130
|
-
|
|
327
|
+
Share state across components:
|
|
131
328
|
|
|
132
|
-
|
|
329
|
+
```javascript
|
|
330
|
+
// stores/userStore.js
|
|
331
|
+
import { createStore } from "ladrillosjs";
|
|
133
332
|
|
|
134
|
-
|
|
333
|
+
export const userStore = createStore({
|
|
334
|
+
user: null,
|
|
335
|
+
isAuthenticated: false,
|
|
336
|
+
});
|
|
135
337
|
|
|
136
|
-
|
|
137
|
-
|
|
338
|
+
export function login(userData) {
|
|
339
|
+
userStore.setState({
|
|
340
|
+
user: userData,
|
|
341
|
+
isAuthenticated: true,
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
export function logout() {
|
|
346
|
+
userStore.setState({
|
|
347
|
+
user: null,
|
|
348
|
+
isAuthenticated: false,
|
|
349
|
+
});
|
|
350
|
+
}
|
|
138
351
|
```
|
|
139
352
|
|
|
140
|
-
|
|
353
|
+
```html
|
|
354
|
+
<!-- header.html -->
|
|
355
|
+
<header>
|
|
356
|
+
<span data-if="isAuthenticated">Welcome, {user.name}!</span>
|
|
357
|
+
<button data-else onclick="showLogin">Login</button>
|
|
358
|
+
</header>
|
|
141
359
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
360
|
+
<script type="module" src="./header-logic.js" bind></script>
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
```javascript
|
|
364
|
+
// header-logic.js
|
|
365
|
+
import { userStore } from "../stores/userStore.js";
|
|
366
|
+
|
|
367
|
+
export default function () {
|
|
368
|
+
// Subscribe to store changes
|
|
369
|
+
userStore.subscribe((state) => {
|
|
370
|
+
this.setState({
|
|
371
|
+
user: state.user,
|
|
372
|
+
isAuthenticated: state.isAuthenticated,
|
|
373
|
+
});
|
|
374
|
+
});
|
|
375
|
+
|
|
376
|
+
this.showLogin = () => {
|
|
377
|
+
this.emit("show-login");
|
|
378
|
+
};
|
|
379
|
+
}
|
|
146
380
|
```
|
|
147
381
|
|
|
148
|
-
|
|
382
|
+
### Shadow DOM
|
|
149
383
|
|
|
150
|
-
|
|
151
|
-
When a component is initialized, any element with `data-bind="key"` will:
|
|
384
|
+
Components use Shadow DOM by default for style encapsulation. To disable:
|
|
152
385
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
-
|
|
386
|
+
```javascript
|
|
387
|
+
// Disable Shadow DOM for a component
|
|
388
|
+
registerComponent("my-component", "./my-component.html", false);
|
|
156
389
|
|
|
157
|
-
|
|
390
|
+
// Multiple components
|
|
391
|
+
registerComponents([
|
|
392
|
+
{ name: "global-styles", path: "./global.html", useShadowDOM: false },
|
|
393
|
+
{ name: "isolated-widget", path: "./widget.html", useShadowDOM: true },
|
|
394
|
+
]);
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
## API Reference
|
|
398
|
+
|
|
399
|
+
### Component Methods
|
|
400
|
+
|
|
401
|
+
| Method | Description |
|
|
402
|
+
| --------------------------------- | -------------------------------------------- |
|
|
403
|
+
| `this.setState(partial)` | Update component state and trigger re-render |
|
|
404
|
+
| `this.emit(eventName, data?)` | Dispatch a custom event |
|
|
405
|
+
| `this.listen(eventName, handler)` | Listen for custom events |
|
|
406
|
+
| `this.querySelector(selector)` | Query element within component |
|
|
407
|
+
| `this.querySelectorAll(selector)` | Query all elements within component |
|
|
408
|
+
|
|
409
|
+
### Store Methods
|
|
410
|
+
|
|
411
|
+
| Method | Description |
|
|
412
|
+
| --------------------------- | -------------------------- |
|
|
413
|
+
| `createStore(initialState)` | Create a new store |
|
|
414
|
+
| `store.getState()` | Get current store state |
|
|
415
|
+
| `store.setState(partial)` | Update store state |
|
|
416
|
+
| `store.subscribe(callback)` | Subscribe to state changes |
|
|
417
|
+
| `store.reset()` | Reset to initial state |
|
|
418
|
+
|
|
419
|
+
## Examples
|
|
420
|
+
|
|
421
|
+
### Component Communication
|
|
158
422
|
|
|
159
423
|
```html
|
|
160
|
-
<!--
|
|
161
|
-
<
|
|
162
|
-
<
|
|
163
|
-
|
|
424
|
+
<!-- parent.html -->
|
|
425
|
+
<div>
|
|
426
|
+
<child-component data-message="Hello"></child-component>
|
|
427
|
+
</div>
|
|
428
|
+
|
|
429
|
+
<script>
|
|
430
|
+
this.listen("child-event", (data) => {
|
|
431
|
+
console.log("Received from child:", data);
|
|
432
|
+
});
|
|
433
|
+
</script>
|
|
434
|
+
|
|
435
|
+
<!-- child.html -->
|
|
436
|
+
<button onclick="sendMessage">{data-message}</button>
|
|
164
437
|
|
|
165
438
|
<script>
|
|
166
|
-
const
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
439
|
+
const sendMessage = () => {
|
|
440
|
+
this.emit("child-event", {
|
|
441
|
+
message: this.state["data-message"],
|
|
442
|
+
timestamp: Date.now(),
|
|
443
|
+
});
|
|
171
444
|
};
|
|
172
445
|
</script>
|
|
173
446
|
```
|
|
447
|
+
|
|
448
|
+
### Dynamic Component Creation
|
|
449
|
+
|
|
450
|
+
```javascript
|
|
451
|
+
// Create components programmatically
|
|
452
|
+
const createCard = (userData) => {
|
|
453
|
+
const card = document.createElement("user-card");
|
|
454
|
+
card.setAttribute("user-id", userData.id);
|
|
455
|
+
card.setAttribute("name", userData.name);
|
|
456
|
+
document.querySelector("#user-list").appendChild(card);
|
|
457
|
+
};
|
|
458
|
+
|
|
459
|
+
// Fetch and create
|
|
460
|
+
fetch("/api/users")
|
|
461
|
+
.then((res) => res.json())
|
|
462
|
+
.then((users) => users.forEach(createCard));
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
## Contributing
|
|
466
|
+
|
|
467
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
468
|
+
|
|
469
|
+
## License
|
|
470
|
+
|
|
471
|
+
MIT License - see [LICENSE](LICENSE) file for details.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export const ladrillos: Ladrillos;
|
|
2
|
+
export type LadrillosComponent = import("../types/LadrilloTypes").LadrillosComponent;
|
|
3
|
+
/** @typedef {import('../types/LadrilloTypes').LadrillosComponent} LadrillosComponent */
|
|
4
|
+
declare class Ladrillos {
|
|
5
|
+
static "__#2@#safeFetch"(url: any): Promise<string>;
|
|
6
|
+
/** @type {Record<string, LadrillosComponent>} */
|
|
7
|
+
components: Record<string, LadrillosComponent>;
|
|
8
|
+
/**
|
|
9
|
+
* Registers a web‐component by fetching its HTML, scripts, and styles.
|
|
10
|
+
* @param {string} name
|
|
11
|
+
* @param {string} path
|
|
12
|
+
* @param {boolean} [useShadowDOM=true]
|
|
13
|
+
*/
|
|
14
|
+
registerComponent(name: string, path: string, useShadowDOM?: boolean): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Registers multiple components with optional concurrency throttling.
|
|
17
|
+
* @param {{name: string, path: string,useShadowDOM:boolean}[]} components
|
|
18
|
+
* @param {number} [concurrency=5] max simultaneous registrations
|
|
19
|
+
*/
|
|
20
|
+
registerComponents(components: {
|
|
21
|
+
name: string;
|
|
22
|
+
path: string;
|
|
23
|
+
useShadowDOM: boolean;
|
|
24
|
+
}[], concurrency?: number): Promise<any>;
|
|
25
|
+
/** @private */
|
|
26
|
+
private _runWithConcurrency;
|
|
27
|
+
/** @private */
|
|
28
|
+
private _defineWebComponent;
|
|
29
|
+
#private;
|
|
30
|
+
}
|
|
31
|
+
export {};
|