@diniz/webcomponents 1.1.2 → 1.1.3

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/dist/README.md ADDED
@@ -0,0 +1,959 @@
1
+ # @diniz/webcomponents
2
+
3
+ A lightweight, framework-agnostic web components library built with vanilla TypeScript. Create modern, reactive UIs using native Web Components API with zero dependencies.
4
+
5
+ ## Features
6
+
7
+ ✨ **Native Web Components** - Built on standard Custom Elements API
8
+ ⚡ **Reactive Signals** - Built-in signal-based reactivity system
9
+ 🎨 **Theme Support** - CSS custom properties for easy theming
10
+ 📦 **Zero Dependencies** - No framework required
11
+ 🔒 **TypeScript** - Full type safety and IntelliSense support
12
+ 🎯 **Tree-shakeable** - Import only what you need
13
+ ♿ **Accessible** - ARIA attributes and keyboard navigation
14
+
15
+ ## 🚀 Live Demo
16
+
17
+ Check out the interactive demo and component examples:
18
+
19
+ **[View Live Demo →](https://rodiniz.github.io/webcomponents/)**
20
+
21
+ ## Installation
22
+
23
+ ```bash
24
+ npm install @diniz/webcomponents
25
+ ```
26
+
27
+ ## Using with Vite (No Framework)
28
+
29
+ This library works seamlessly with Vite without requiring any framework. Here's how to set up a vanilla JavaScript/TypeScript project:
30
+
31
+ ### 1. Create a New Vite Project
32
+
33
+ ```bash
34
+ # Create a new Vite project with vanilla TypeScript template
35
+ npm create vite@latest my-app -- --template vanilla-ts
36
+ cd my-app
37
+ npm install
38
+ ```
39
+
40
+ ### 2. Install the Library
41
+
42
+ ```bash
43
+ npm install @diniz/webcomponents
44
+ ```
45
+
46
+ ### 3. Import Components in Your Main File
47
+
48
+ In your `src/main.ts` file:
49
+
50
+ ```typescript
51
+ import '@diniz/webcomponents';
52
+ import '@diniz/webcomponents/dist/style.css'; // Import styles
53
+
54
+ // Now you can use the components in your HTML
55
+ document.querySelector<HTMLDivElement>('#app')!.innerHTML = `
56
+ <div>
57
+ <h1>My Web Components App</h1>
58
+ <ui-button variant="primary" size="md">Click Me</ui-button>
59
+ <ui-date-picker format="DD/MM/YYYY"></ui-date-picker>
60
+ </div>
61
+ `;
62
+ ```
63
+
64
+ ### 4. Use Components in HTML
65
+
66
+ In your `index.html`:
67
+
68
+ ```html
69
+ <!DOCTYPE html>
70
+ <html lang="en">
71
+ <head>
72
+ <meta charset="UTF-8" />
73
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
74
+ <title>My App</title>
75
+ </head>
76
+ <body>
77
+ <div id="app">
78
+ <ui-button variant="primary">Click Me</ui-button>
79
+ <ui-date-picker format="DD/MM/YYYY"></ui-date-picker>
80
+ <ui-table></ui-table>
81
+ </div>
82
+ <script type="module" src="/src/main.ts"></script>
83
+ </body>
84
+ </html>
85
+ ```
86
+
87
+ ### 5. Add Event Listeners (Optional)
88
+
89
+ ```typescript
90
+ // Wait for components to be defined
91
+ customElements.whenDefined('ui-button').then(() => {
92
+ const button = document.querySelector('ui-button');
93
+ button?.addEventListener('click', () => {
94
+ console.log('Button clicked!');
95
+ });
96
+ });
97
+
98
+ // Listen to custom events
99
+ const picker = document.querySelector('ui-date-picker');
100
+ picker?.addEventListener('date-change', ((e: CustomEvent) => {
101
+ console.log('Date selected:', e.detail.value);
102
+ }) as EventListener);
103
+ ```
104
+
105
+ ### 6. TypeScript Support
106
+
107
+ For full TypeScript support, create a `src/types.d.ts` file:
108
+
109
+ ```typescript
110
+ declare module '@diniz/webcomponents' {
111
+ export interface UIButton extends HTMLElement {
112
+ variant: 'primary' | 'secondary' | 'ghost';
113
+ size: 'sm' | 'md' | 'lg';
114
+ icon?: string;
115
+ disabled?: boolean;
116
+ }
117
+
118
+ export interface UIDatePicker extends HTMLElement {
119
+ format: string;
120
+ value: string;
121
+ min?: string;
122
+ max?: string;
123
+ }
124
+
125
+ // Add other component interfaces as needed
126
+ }
127
+
128
+ declare global {
129
+ interface HTMLElementTagNameMap {
130
+ 'ui-button': import('@diniz/webcomponents').UIButton;
131
+ 'ui-date-picker': import('@diniz/webcomponents').UIDatePicker;
132
+ // Add other components as needed
133
+ }
134
+ }
135
+ ```
136
+
137
+ ### 7. Build for Production
138
+
139
+ ```bash
140
+ npm run build
141
+ ```
142
+
143
+ The build output will be in the `dist` folder, ready to deploy to any static hosting service.
144
+
145
+ ### Tree-shaking (Import Only What You Need)
146
+
147
+ You can import individual components to reduce bundle size:
148
+
149
+ ```typescript
150
+ // Import only specific components
151
+ import { UIButton } from '@diniz/webcomponents';
152
+ import '@diniz/webcomponents/dist/style.css';
153
+
154
+ // The component is automatically registered
155
+ // Now you can use <ui-button> in your HTML
156
+ ```
157
+
158
+ ### Configuration Tips
159
+
160
+ **Vite Config** - No special configuration needed! Web Components work out of the box with Vite.
161
+
162
+ **CSS Customization** - Override CSS custom properties to match your theme:
163
+
164
+ ```css
165
+ :root {
166
+ --color-primary: #3b82f6;
167
+ --color-secondary: #8b5cf6;
168
+ --color-success: #10b981;
169
+ --color-danger: #ef4444;
170
+ --color-warning: #f59e0b;
171
+ --color-info: #06b6d4;
172
+
173
+ --radius-sm: 0.25rem;
174
+ --radius-md: 0.375rem;
175
+ --radius-lg: 0.5rem;
176
+ }
177
+ ```
178
+ **Update `src/main.ts`:**
179
+ ```typescript
180
+ import '@diniz/webcomponents';
181
+ import '@diniz/webcomponents/dist/style.css';
182
+
183
+ document.querySelector<HTMLDivElement>('#app')!.innerHTML = `
184
+ <div>
185
+ <h1>My Web Components App</h1>
186
+ <ui-button variant="primary">Click Me</ui-button>
187
+ <ui-date-picker format="DD/MM/YYYY"></ui-date-picker>
188
+ <ui-table id="myTable"></ui-table>
189
+ </div>
190
+ `;
191
+
192
+ // Add some data to the table
193
+ const table = document.getElementById('myTable') as any;
194
+ table.data = {
195
+ columns: [
196
+ { key: 'name', label: 'Name' },
197
+ { key: 'role', label: 'Role' }
198
+ ],
199
+ rows: [
200
+ { name: 'Alice', role: 'Admin' },
201
+ { name: 'Bob', role: 'User' }
202
+ ]
203
+ };
204
+ ```
205
+
206
+ ### Using via CDN or Direct Import
207
+
208
+ ```html
209
+ <script type="module">
210
+ import '@diniz/webcomponents';
211
+ </script>
212
+
213
+ <ui-button variant="primary">Click Me</ui-button>
214
+ <ui-date-picker format="DD/MM/YYYY"></ui-date-picker>
215
+ <ui-table></ui-table>
216
+ ```
217
+
218
+ ## Components
219
+
220
+ ### 🔘 Button (`ui-button`)
221
+
222
+ A versatile button component with multiple variants, sizes, and icon support.
223
+
224
+ **Features:**
225
+ - 3 variants: `primary`, `secondary`, `ghost`
226
+ - 3 sizes: `sm`, `md`, `lg`
227
+ - Icon support with [Feather Icons](https://feathericons.com/)
228
+ - Icon positioning (left/right)
229
+ - Icon-only buttons
230
+ - Disabled state support
231
+ - Button type support
232
+ - Smooth transitions and hover effects
233
+
234
+ **Usage:**
235
+ ```html
236
+ <ui-button variant="primary" size="md">Primary Button</ui-button>
237
+ <ui-button variant="secondary" size="sm">Secondary</ui-button>
238
+ <ui-button variant="ghost" disabled>Disabled</ui-button>
239
+
240
+ <!-- With icons -->
241
+ <ui-button variant="primary" icon="check">Save</ui-button>
242
+ <ui-button variant="secondary" icon="trash-2" icon-position="right">Delete</ui-button>
243
+ <ui-button variant="ghost" icon="settings"></ui-button>
244
+ ```
245
+
246
+ **Attributes:**
247
+ - `variant` - Button style (`primary` | `secondary` | `ghost`)
248
+ - `size` - Button size (`sm` | `md` | `lg`)
249
+ - `icon` - Icon name from Feather Icons
250
+ - `icon-position` - Icon position (`left` | `right`, default: `left`)
251
+ - `disabled` - Disable the button
252
+ - `type` - Button type (`button` | `submit` | `reset`)
253
+
254
+ ---
255
+
256
+ ### 📅 Date Picker (`ui-date-picker`)
257
+
258
+ A customizable date picker with multiple format options and calendar support.
259
+
260
+ **Features:**
261
+ - 5 date formats: `YYYY-MM-DD`, `DD/MM/YYYY`, `MM/DD/YYYY`, `DD-MM-YYYY`, `MM-DD-YYYY`
262
+ - Native calendar picker integration
263
+ - Min/max date constraints
264
+ - Text input with format validation
265
+ - Real-time format conversion
266
+ - Disabled state support
267
+ - Custom events for date changes
268
+
269
+ **Usage:**
270
+ ```html
271
+ <ui-date-picker
272
+ format="DD/MM/YYYY"
273
+ value="2026-02-26"
274
+ min="2026-01-01"
275
+ max="2026-12-31"
276
+ ></ui-date-picker>
277
+
278
+ <script>
279
+ const picker = document.querySelector('ui-date-picker');
280
+
281
+ picker.addEventListener('date-change', (e) => {
282
+ console.log('ISO:', e.detail.value);
283
+ console.log('Formatted:', e.detail.formattedValue);
284
+ });
285
+ </script>
286
+ ```
287
+
288
+ **Attributes:**
289
+ - `format` - Date display format
290
+ - `value` - Date value in ISO format (YYYY-MM-DD)
291
+ - `min` - Minimum date (ISO format)
292
+ - `max` - Maximum date (ISO format)
293
+ - `disabled` - Disable the picker
294
+ - `placeholder` - Placeholder text
295
+
296
+ **Methods:**
297
+ - `getISOValue()` - Get date in ISO format
298
+ - `getFormattedValue()` - Get date in display format
299
+ - `setValue(isoDate)` - Set the date value
300
+ - `clear()` - Clear the date
301
+
302
+ **Events:**
303
+ - `date-change` - Fired when date changes
304
+ - `date-input` - Fired during input
305
+
306
+ ---
307
+
308
+ ### 📋 Table (`ui-table`)
309
+
310
+ A dynamic data table with customizable columns and alignment.
311
+
312
+ **Features:**
313
+ - Dynamic column configuration
314
+ - Text alignment per column (left, center, right)
315
+ - Responsive layout
316
+ - Automatic row rendering
317
+ - Theme-aware styling
318
+
319
+ **Usage:**
320
+ ```html
321
+ <ui-table id="myTable"></ui-table>
322
+
323
+ <script type="module">
324
+ const table = document.getElementById('myTable');
325
+
326
+ table.data = {
327
+ columns: [
328
+ { key: 'name', label: 'Name' },
329
+ { key: 'role', label: 'Role' },
330
+ { key: 'score', label: 'Score', align: 'right' }
331
+ ],
332
+ rows: [
333
+ { name: 'Alice', role: 'Admin', score: 95 },
334
+ { name: 'Bob', role: 'User', score: 87 }
335
+ ]
336
+ };
337
+ </script>
338
+ ```
339
+
340
+ **Properties:**
341
+ - `data` - Object with `columns` and `rows`
342
+ - `columns`: Array of `{ key, label, align? }`
343
+ - `rows`: Array of objects matching column keys
344
+
345
+ ---
346
+
347
+ ### 📄 Pagination (`ui-pagination`)
348
+
349
+ Smart pagination component with ellipsis for large page counts.
350
+
351
+ **Features:**
352
+ - Automatic page number generation
353
+ - Smart ellipsis for large page counts
354
+ - Previous/Next navigation
355
+ - "Showing X to Y of Z" info display
356
+ - Disabled states for edge pages
357
+ - Custom events for page changes
358
+ - ARIA labels for accessibility
359
+
360
+ **Usage:**
361
+ ```html
362
+ <ui-pagination
363
+ total="250"
364
+ current-page="5"
365
+ page-size="10"
366
+ ></ui-pagination>
367
+
368
+ <script>
369
+ const pagination = document.querySelector('ui-pagination');
370
+
371
+ pagination.addEventListener('page-change', (e) => {
372
+ console.log('Page:', e.detail.page);
373
+ console.log('Total Pages:', e.detail.totalPages);
374
+ // Load new data...
375
+ });
376
+ </script>
377
+ ```
378
+
379
+ **Attributes/Properties:**
380
+ - `total` - Total number of items
381
+ - `current-page` - Current page number
382
+ - `page-size` - Items per page (default: 10)
383
+
384
+ **Computed Properties:**
385
+ - `totalPages` - Total number of pages
386
+
387
+ **Events:**
388
+ - `page-change` - Fired when page changes, includes pagination details
389
+
390
+ ---
391
+
392
+ ### 📝 Input (`ui-input`)
393
+
394
+ Advanced form input with built-in validation and error handling.
395
+
396
+ **Features:**
397
+ - Multiple input types: `text`, `email`, `password`, `number`, `tel`, `url`
398
+ - Built-in validation rules:
399
+ - Email domain validation
400
+ - Password matching
401
+ - Min/max length
402
+ - Regex patterns
403
+ - Custom validators
404
+ - Real-time validation feedback
405
+ - Error message display
406
+ - Touched state tracking
407
+ - Disabled state support
408
+
409
+ **Usage:**
410
+ ```html
411
+ <ui-input
412
+ type="email"
413
+ label="Email"
414
+ placeholder="you@example.com"
415
+ required
416
+ validate="emailDomain:company.com"
417
+ ></ui-input>
418
+
419
+ <ui-input
420
+ type="password"
421
+ label="Password"
422
+ minlength="8"
423
+ required
424
+ ></ui-input>
425
+ ```
426
+
427
+ **Attributes:**
428
+ - `type` - Input type
429
+ - `label` - Label text
430
+ - `placeholder` - Placeholder text
431
+ - `required` - Required field
432
+ - `pattern` - Regex pattern
433
+ - `minlength` / `maxlength` - Length constraints
434
+ - `min` / `max` - Number constraints
435
+ - `error-message` - Custom error message
436
+ - `disabled` - Disable input
437
+ - `name` - Form field name
438
+ - `validate` - Validation rule (e.g., `emailDomain:company.com`)
439
+
440
+ **State:**
441
+ - `value` - Current input value
442
+ - `valid` - Validation state
443
+ - `touched` - Whether field has been interacted with
444
+ - `error` - Current error message
445
+
446
+ ---
447
+
448
+ ### 🪟 Modal (`ui-modal`)
449
+
450
+ Responsive modal dialog with customizable sizes and behaviors.
451
+
452
+ **Features:**
453
+ - 5 size options: `sm`, `md`, `lg`, `xl`, `full`
454
+ - Auto-close on Escape key (configurable)
455
+ - Auto-close on backdrop click (configurable)
456
+ - Smooth animations (fade in, slide up)
457
+ - Header, body, and footer slots
458
+ - Programmatic open/close API
459
+ - Custom events
460
+ - Body scroll lock when open
461
+
462
+ **Usage:**
463
+ ```html
464
+ <ui-button id="openModal">Open Modal</ui-button>
465
+
466
+ <ui-modal id="myModal" title="Welcome!" size="md">
467
+ <p>This is the modal content.</p>
468
+ <p>You can include any HTML here.</p>
469
+
470
+ <div slot="footer">
471
+ <ui-button id="closeBtn" variant="secondary">Cancel</ui-button>
472
+ <ui-button id="confirmBtn" variant="primary">Confirm</ui-button>
473
+ </div>
474
+ </ui-modal>
475
+
476
+ <script>
477
+ const modal = document.getElementById('myModal');
478
+ const openBtn = document.getElementById('openModal');
479
+ const closeBtn = document.getElementById('closeBtn');
480
+
481
+ openBtn.addEventListener('click', () => modal.open());
482
+ closeBtn.addEventListener('click', () => modal.close());
483
+
484
+ modal.addEventListener('modal-close', () => {
485
+ console.log('Modal closed');
486
+ });
487
+ </script>
488
+ ```
489
+
490
+ **Attributes:**
491
+ - `title` - Modal title text
492
+ - `size` - Modal size (`sm` | `md` | `lg` | `xl` | `full`)
493
+ - `open` - Open state attribute
494
+ - `no-close-on-escape` - Disable closing on Escape key
495
+ - `no-close-on-backdrop` - Disable closing on backdrop click
496
+
497
+ **Methods:**
498
+ - `open()` - Open the modal
499
+ - `close()` - Close the modal
500
+
501
+ **Events:**
502
+ - `modal-open` - Fired when modal opens
503
+ - `modal-close` - Fired when modal closes
504
+
505
+ ---
506
+
507
+ ### 📋 Select (`ui-select`)
508
+
509
+ Customizable dropdown select with search capability.
510
+
511
+ **Features:**
512
+ - JSON-based options configuration
513
+ - Searchable dropdown (optional)
514
+ - Keyboard navigation
515
+ - Disabled options support
516
+ - Custom placeholder text
517
+ - Change events with full option details
518
+ - Click-outside to close
519
+ - Smooth animations
520
+ - Theme-aware styling
521
+
522
+ **Usage:**
523
+ ```html
524
+ <ui-select
525
+ id="mySelect"
526
+ label="Choose a Country"
527
+ placeholder="Select country..."
528
+ searchable
529
+ ></ui-select>
530
+
531
+ <script>
532
+ const select = document.getElementById('mySelect');
533
+
534
+ // Set options
535
+ const options = [
536
+ { value: 'us', label: 'United States' },
537
+ { value: 'uk', label: 'United Kingdom' },
538
+ { value: 'ca', label: 'Canada' },
539
+ { value: 'au', label: 'Australia', disabled: true }
540
+ ];
541
+
542
+ select.setAttribute('options', JSON.stringify(options));
543
+
544
+ // Set initial value
545
+ select.setAttribute('value', 'us');
546
+
547
+ // Listen for changes
548
+ select.addEventListener('select-change', (e) => {
549
+ console.log('Value:', e.detail.value);
550
+ console.log('Option:', e.detail.option);
551
+ });
552
+ </script>
553
+ ```
554
+
555
+ **Attributes:**
556
+ - `label` - Label text above select
557
+ - `placeholder` - Placeholder when no selection
558
+ - `options` - JSON string of options array
559
+ - `value` - Currently selected value
560
+ - `disabled` - Disable the select
561
+ - `searchable` - Enable search functionality
562
+
563
+ **Option Format:**
564
+ ```typescript
565
+ {
566
+ value: string; // The option value
567
+ label: string; // Display text
568
+ disabled?: boolean; // Optional: disable option
569
+ }
570
+ ```
571
+
572
+ **Events:**
573
+ - `select-change` - Fired when selection changes
574
+ - `detail.value` - Selected value
575
+ - `detail.option` - Full option object
576
+
577
+ ---
578
+
579
+ ### ☑️ Checkbox (`ui-checkbox`)
580
+
581
+ Flexible checkbox with indeterminate state support.
582
+
583
+ **Features:**
584
+ - 3 sizes: `sm`, `md`, `lg`
585
+ - Checked/unchecked states
586
+ - Indeterminate state (useful for "select all")
587
+ - Disabled state
588
+ - Label support (attribute or slot)
589
+ - Programmatic API
590
+ - Custom events
591
+ - Smooth animations and transitions
592
+ - Theme-aware styling
593
+
594
+ **Usage:**
595
+ ```html
596
+ <!-- Basic usage -->
597
+ <ui-checkbox label="Accept terms"></ui-checkbox>
598
+ <ui-checkbox label="Subscribe" checked></ui-checkbox>
599
+ <ui-checkbox label="Disabled" disabled></ui-checkbox>
600
+
601
+ <!-- With sizes -->
602
+ <ui-checkbox label="Small" size="sm"></ui-checkbox>
603
+ <ui-checkbox label="Medium" size="md"></ui-checkbox>
604
+ <ui-checkbox label="Large" size="lg"></ui-checkbox>
605
+
606
+ <!-- Programmatic usage -->
607
+ <ui-checkbox id="myCheckbox" label="Select All"></ui-checkbox>
608
+
609
+ <script>
610
+ const checkbox = document.getElementById('myCheckbox');
611
+
612
+ // Listen for changes
613
+ checkbox.addEventListener('checkbox-change', (e) => {
614
+ console.log('Checked:', e.detail.checked);
615
+ });
616
+
617
+ // Set states programmatically
618
+ checkbox.setChecked(true);
619
+ checkbox.setIndeterminate(true);
620
+ </script>
621
+ ```
622
+
623
+ **Attributes:**
624
+ - `label` - Label text
625
+ - `checked` - Checked state
626
+ - `indeterminate` - Indeterminate state
627
+ - `disabled` - Disable checkbox
628
+ - `size` - Checkbox size (`sm` | `md` | `lg`)
629
+
630
+ **Methods:**
631
+ - `setChecked(checked: boolean)` - Set checked state
632
+ - `setIndeterminate(indeterminate: boolean)` - Set indeterminate state
633
+
634
+ **Events:**
635
+ - `checkbox-change` - Fired when state changes
636
+ - `detail.checked` - New checked state
637
+
638
+ ---
639
+
640
+ ### 🎯 Sidebar (`app-sidebar`)
641
+
642
+ Navigation sidebar component with links.
643
+
644
+ **Features:**
645
+ - Workspace navigation
646
+ - Active link highlighting (via routing)
647
+ - Theme-aware styling
648
+
649
+ **Usage:**
650
+ ```html
651
+ <app-sidebar></app-sidebar>
652
+ ```
653
+
654
+ ---
655
+
656
+ ### 📐 Layout (`app-layout`)
657
+
658
+ Application layout wrapper with navigation and sidebar.
659
+
660
+ **Features:**
661
+ - Top navigation bar
662
+ - Sidebar integration
663
+ - Main content area with slot
664
+ - Responsive layout
665
+
666
+ **Usage:**
667
+ ```html
668
+ <app-layout>
669
+ <your-page-component></your-page-component>
670
+ </app-layout>
671
+ ```
672
+
673
+ ---
674
+
675
+ ## Core Features
676
+
677
+ ### Base Component
678
+
679
+ All components extend `BaseComponent` which provides:
680
+
681
+ **Signal-based Reactivity:**
682
+ ```typescript
683
+ class MyComponent extends BaseComponent {
684
+ private count = this.useSignal(0);
685
+
686
+ connectedCallback() {
687
+ super.connectedCallback();
688
+ // count.set() automatically triggers re-render
689
+ this.count.set(this.count.get() + 1);
690
+ }
691
+ }
692
+ ```
693
+
694
+ **State Management:**
695
+ ```typescript
696
+ class MyComponent extends BaseComponent<{ user: string }> {
697
+ constructor() {
698
+ super();
699
+ this.state = { user: '' };
700
+ }
701
+
702
+ updateUser() {
703
+ this.setState({ user: 'Alice' }); // Triggers re-render
704
+ }
705
+ }
706
+ ```
707
+
708
+ ### Router
709
+
710
+ Built-in client-side router with layouts:
711
+
712
+ ```typescript
713
+ const routes = [
714
+ {
715
+ path: '/',
716
+ layout: 'app-layout',
717
+ load: () => import('./features/home/home-page'),
718
+ component: 'home-page'
719
+ }
720
+ ];
721
+ ```
722
+
723
+ ### Store
724
+
725
+ Global state management:
726
+
727
+ ```typescript
728
+ import { store } from './core/store';
729
+
730
+ store.setState({ theme: 'dark' });
731
+ const currentState = store.getState();
732
+
733
+ store.subscribe(state => {
734
+ console.log('State changed:', state);
735
+ });
736
+ ```
737
+
738
+ ### HTTP Client
739
+
740
+ Lightweight HTTP client with interceptor support for API requests:
741
+
742
+ ```typescript
743
+ import { http } from '@diniz/webcomponents';
744
+
745
+ // Set base URL for all requests
746
+ http.setBaseURL('https://api.example.com');
747
+
748
+ // Set default headers
749
+ http.setDefaultHeaders({ 'Authorization': 'Bearer token' });
750
+
751
+ // Make requests
752
+ const users = await http.get<User[]>('/users');
753
+ const newUser = await http.post<User>('/users', { name: 'Alice' });
754
+ await http.put(`/users/${id}`, updatedData);
755
+ await http.delete(`/users/${id}`);
756
+ ```
757
+
758
+ **Request Interceptors:**
759
+
760
+ ```typescript
761
+ // Add auth token to every request
762
+ http.interceptors.request.use((config) => {
763
+ const token = localStorage.getItem('auth_token');
764
+ if (token) {
765
+ config.headers = config.headers || {};
766
+ config.headers['Authorization'] = `Bearer ${token}`;
767
+ }
768
+ return config;
769
+ });
770
+
771
+ // Handle request errors
772
+ http.interceptors.request.use(
773
+ (config) => config,
774
+ (error) => {
775
+ console.error('Request failed:', error);
776
+ throw error;
777
+ }
778
+ );
779
+ ```
780
+
781
+ **Response Interceptors:**
782
+
783
+ ```typescript
784
+ // Transform response data
785
+ http.interceptors.response.use((response) => {
786
+ // Unwrap API response if it's nested
787
+ if (response.data?.result) {
788
+ response.data = response.data.result;
789
+ }
790
+ return response;
791
+ });
792
+
793
+ // Handle errors globally
794
+ http.interceptors.response.use(
795
+ (response) => response,
796
+ (error) => {
797
+ if (error.response?.status === 401) {
798
+ // Handle unauthorized
799
+ localStorage.removeItem('auth_token');
800
+ window.location.href = '/login';
801
+ }
802
+ throw error;
803
+ }
804
+ );
805
+ ```
806
+
807
+ **Methods:**
808
+
809
+ - `get<T>(url, config?)` - GET request
810
+ - `post<T>(url, data?, config?)` - POST request
811
+ - `put<T>(url, data?, config?)` - PUT request
812
+ - `patch<T>(url, data?, config?)` - PATCH request
813
+ - `delete<T>(url, config?)` - DELETE request
814
+ - `head<T>(url, config?)` - HEAD request
815
+
816
+ **Configuration:**
817
+
818
+ ```typescript
819
+ interface RequestConfig {
820
+ method?: string;
821
+ headers?: Record<string, string>;
822
+ body?: string | FormData | null;
823
+ timeout?: number; // Default: 30000ms
824
+ }
825
+ ```
826
+
827
+ **Features:**
828
+
829
+ - ✅ Request/response interceptors with error handling
830
+ - ✅ Automatic JSON serialization/deserialization
831
+ - ✅ Timeout support (default 30s)
832
+ - ✅ Global headers and base URL configuration
833
+ - ✅ FormData support for file uploads
834
+ - ✅ TypeScript generics for type-safe responses
835
+ - ✅ Automatic error messages with status codes
836
+
837
+ ---
838
+
839
+ ## Theming
840
+
841
+ All components use CSS custom properties for easy theming:
842
+
843
+ ```css
844
+ :root {
845
+ --color-primary: #24ec71;
846
+ --color-primary-contrast: #ffffff;
847
+ --color-ink: #0f172a;
848
+ --color-muted: #f1f5f9;
849
+ --color-border: #e2e8f0;
850
+ --radius-md: 12px;
851
+ --radius-pill: 999px;
852
+ }
853
+ ```
854
+
855
+ ---
856
+
857
+ ## Dependencies
858
+
859
+ ### Icons
860
+
861
+ This library uses **[Feather Icons](https://feathericons.com/)** for beautiful, minimal SVG icons. Feather provides a consistent set of 286 icons perfect for UI components.
862
+
863
+ ```typescript
864
+ import feather from 'feather-icons';
865
+
866
+ // Use icons in components
867
+ <ui-button icon="plus">Add Item</ui-button>
868
+ <ui-button icon="trash-2" variant="danger">Delete</ui-button>
869
+ ```
870
+
871
+ [Browse all available Feather icons →](https://feathericons.com/)
872
+
873
+ ---
874
+
875
+ ## Bundle Size
876
+
877
+ @diniz/webcomponents is extremely lightweight with zero runtime dependencies:
878
+
879
+ | Package | Size (minified) | Size (gzipped) |
880
+ |---------|-----------------|----------------|
881
+ | **@diniz/webcomponents** | ~45KB | ~12KB |
882
+ | Vue 3 + Router | ~185KB | ~65KB |
883
+ | React 18 + Router | ~245KB | ~85KB |
884
+ | Angular 15 | ~500KB+ | ~150KB+ |
885
+ | Svelte | ~60KB | ~15KB |
886
+
887
+ *Sizes are approximate and vary based on included components and tree-shaking effectiveness*
888
+
889
+ **Why Web Components?**
890
+ - ✅ No framework overhead - use with any framework or vanilla JS
891
+ - ✅ Smaller initial bundle size than traditional frameworks
892
+ - ✅ Progressive enhancement - works without JavaScript
893
+ - ✅ Share components across different projects/frameworks
894
+ - ✅ Built-in browser APIs - no external polyfills needed for modern browsers
895
+
896
+ ---
897
+
898
+ ## Browser Support
899
+
900
+ - ✅ Chrome/Edge (latest)
901
+ - ✅ Firefox (latest)
902
+ - ✅ Safari (latest)
903
+ - ✅ All modern browsers with Custom Elements support
904
+
905
+ ---
906
+
907
+ ## Development
908
+
909
+ ```bash
910
+ # Install dependencies
911
+ npm install
912
+
913
+ # Start dev server
914
+ npm run dev
915
+
916
+ # Build library
917
+ npm run build:lib
918
+
919
+ # Build production app
920
+ npm run build:prod
921
+ ```
922
+
923
+ ---
924
+
925
+ ## Project Structure
926
+
927
+ ```
928
+ src/
929
+ ├── core/
930
+ │ ├── base-component.ts # Base class with signals
931
+ │ ├── router.ts # Client-side routing
932
+ │ └── store.ts # Global state management
933
+ ├── shared/
934
+ │ └── components/ # Reusable UI components
935
+ │ ├── button.ts
936
+ │ ├── checkbox.ts
937
+ │ ├── date-picker.ts
938
+ │ ├── input.ts
939
+ │ ├── modal.ts
940
+ │ ├── pagination.ts
941
+ │ ├── select.ts
942
+ │ └── table.ts
943
+ ├── layouts/
944
+ │ └── app-layout.ts # Application shell
945
+ ├── features/ # Page components
946
+ └── styles/
947
+ └── theme.css # Global theme variables
948
+ ```
949
+ ## Contributing
950
+
951
+ Contributions are welcome! Please feel free to submit a Pull Request.
952
+
953
+ ---
954
+
955
+ ## License
956
+
957
+ MIT © Rodrigo Diniz
958
+
959
+