zabi-components 2.0.3 → 2.1.1
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 +306 -187
- package/dist/Checkbox-Dwvh3lCd.js +302 -0
- package/dist/Navigation-BxP-osMQ.js +78 -0
- package/dist/OptimizedImage-8a380fXi.js +593 -0
- package/dist/ThemeToggle-Cm25ThjX.js +42 -0
- package/dist/atoms/index.js +16 -21
- package/dist/index/index.js +41 -90
- package/dist/molecules/index.js +517 -13
- package/dist/organisms/index.js +1 -1
- package/dist/props-B4BdFk2B.js +2339 -0
- package/package.json +1 -1
- package/dist/Card-YmnHW5Dv.js +0 -106
- package/dist/Navigation-DE8_K3bU.js +0 -79
- package/dist/PerformanceMonitor-CZWEjSY0.js +0 -1230
- package/dist/SelectedCardInfo-1FErRXDl.js +0 -509
- package/dist/ThemeToggle-Dt8hE3_o.js +0 -35
- package/dist/props-ChfwWtCN.js +0 -2513
package/README.md
CHANGED
|
@@ -9,10 +9,12 @@ A clean, minimal Svelte component library built with TypeScript and Tailwind CSS
|
|
|
9
9
|
## Features
|
|
10
10
|
|
|
11
11
|
- 🎯 **TypeScript First** - Full TypeScript support with comprehensive type definitions
|
|
12
|
-
- 🎨 **
|
|
12
|
+
- 🎨 **Semantic Color System** - Built-in semantic colors with automatic dark mode support
|
|
13
|
+
- 🌙 **Dark Mode Ready** - Automatic dark mode switching with CSS custom properties
|
|
13
14
|
- ♿ **Accessibility First** - ARIA compliant components with keyboard navigation support
|
|
14
15
|
- 📱 **Responsive Design** - Mobile-first approach with responsive utilities
|
|
15
16
|
- 🧩 **Clean API** - Simple, intuitive component APIs with minimal props
|
|
17
|
+
- 🔧 **Utility Functions** - Reusable variant utilities for consistent styling
|
|
16
18
|
- 📦 **Tree Shakeable** - Import only what you need
|
|
17
19
|
- ✅ **Production Ready** - Fully tested and optimized for production use
|
|
18
20
|
- 🚀 **Modern CSS** - CSS-only positioning, animations, and interactions
|
|
@@ -59,19 +61,22 @@ import type { ButtonEvents, InputEvents } from 'zabi-components/types';
|
|
|
59
61
|
```svelte
|
|
60
62
|
<script lang="ts">
|
|
61
63
|
// Clean Components - Less is More
|
|
62
|
-
import { Card, Form, Layout, Navigation, Button, Input } from 'zabi-components';
|
|
64
|
+
import { Card, Form, Layout, Navigation, Button, Input, Textarea } from 'zabi-components';
|
|
63
65
|
|
|
64
66
|
let formData = {
|
|
65
67
|
name: '',
|
|
66
68
|
email: '',
|
|
69
|
+
message: '',
|
|
67
70
|
};
|
|
68
71
|
|
|
69
|
-
function handleFormSubmit(event:
|
|
70
|
-
|
|
72
|
+
function handleFormSubmit(event: SubmitEvent) {
|
|
73
|
+
const formData = new FormData(event.target as HTMLFormElement);
|
|
74
|
+
const data = Object.fromEntries(formData.entries());
|
|
75
|
+
console.log('Form submitted:', data);
|
|
71
76
|
}
|
|
72
77
|
|
|
73
|
-
function handleCardClick(event:
|
|
74
|
-
console.log('Card clicked:', event
|
|
78
|
+
function handleCardClick(event: MouseEvent) {
|
|
79
|
+
console.log('Card clicked:', event);
|
|
75
80
|
}
|
|
76
81
|
|
|
77
82
|
const navItems = [
|
|
@@ -88,17 +93,61 @@ import type { ButtonEvents, InputEvents } from 'zabi-components/types';
|
|
|
88
93
|
</div>
|
|
89
94
|
|
|
90
95
|
<main class="container mx-auto p-6">
|
|
91
|
-
|
|
96
|
+
<!-- Semantic Color Variants -->
|
|
97
|
+
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 mb-8">
|
|
98
|
+
<Card title="Default Card" variant="default" on:click={handleCardClick}>
|
|
99
|
+
This is a default card with semantic colors.
|
|
100
|
+
</Card>
|
|
101
|
+
<Card title="Success Card" variant="success" on:click={handleCardClick}>
|
|
102
|
+
This card indicates a successful action.
|
|
103
|
+
</Card>
|
|
104
|
+
<Card title="Warning Card" variant="warning" on:click={handleCardClick}>
|
|
105
|
+
This card shows a warning state.
|
|
106
|
+
</Card>
|
|
107
|
+
<Card title="Error Card" variant="error" on:click={handleCardClick}>
|
|
108
|
+
This card indicates an error state.
|
|
109
|
+
</Card>
|
|
110
|
+
<Card title="Info Card" variant="info" on:click={handleCardClick}>
|
|
111
|
+
This card provides informational content.
|
|
112
|
+
</Card>
|
|
113
|
+
</div>
|
|
92
114
|
|
|
93
115
|
<Form on:submit={handleFormSubmit}>
|
|
94
116
|
<div class="form-field">
|
|
95
|
-
<
|
|
96
|
-
|
|
117
|
+
<Input
|
|
118
|
+
id="name"
|
|
119
|
+
name="name"
|
|
120
|
+
value={formData.name}
|
|
121
|
+
on:input={(e) => formData.name = e.target.value}
|
|
122
|
+
label="Name"
|
|
123
|
+
placeholder="Enter your name"
|
|
124
|
+
variant="default"
|
|
125
|
+
/>
|
|
97
126
|
</div>
|
|
98
127
|
|
|
99
128
|
<div class="form-field">
|
|
100
|
-
<
|
|
101
|
-
|
|
129
|
+
<Input
|
|
130
|
+
id="email"
|
|
131
|
+
name="email"
|
|
132
|
+
type="email"
|
|
133
|
+
value={formData.email}
|
|
134
|
+
on:input={(e) => formData.email = e.target.value}
|
|
135
|
+
label="Email"
|
|
136
|
+
placeholder="Enter your email"
|
|
137
|
+
variant="success"
|
|
138
|
+
/>
|
|
139
|
+
</div>
|
|
140
|
+
|
|
141
|
+
<div class="form-field">
|
|
142
|
+
<Textarea
|
|
143
|
+
id="message"
|
|
144
|
+
name="message"
|
|
145
|
+
value={formData.message}
|
|
146
|
+
on:input={(e) => formData.message = e.target.value}
|
|
147
|
+
label="Message"
|
|
148
|
+
placeholder="Enter your message"
|
|
149
|
+
variant="default"
|
|
150
|
+
/>
|
|
102
151
|
</div>
|
|
103
152
|
|
|
104
153
|
<div class="form-actions">
|
|
@@ -145,6 +194,75 @@ import type { ButtonEvents, InputEvents } from 'zabi-components/types';
|
|
|
145
194
|
| **ColorPicker** | Atom | Color selection | Simple color grid |
|
|
146
195
|
| **SlideUp** | Molecule | Slide-up panel | CSS-only animations |
|
|
147
196
|
|
|
197
|
+
## Semantic Color System
|
|
198
|
+
|
|
199
|
+
Zabi Components includes a comprehensive semantic color system that automatically supports dark mode and provides consistent styling across all components.
|
|
200
|
+
|
|
201
|
+
### Available Variants
|
|
202
|
+
|
|
203
|
+
All components support these semantic color variants:
|
|
204
|
+
|
|
205
|
+
- **`default`** - Standard appearance with primary colors
|
|
206
|
+
- **`success`** - Green colors for positive states
|
|
207
|
+
- **`warning`** - Yellow/amber colors for caution states
|
|
208
|
+
- **`error`** - Red colors for error states
|
|
209
|
+
- **`info`** - Blue colors for informational states
|
|
210
|
+
|
|
211
|
+
### Usage Examples
|
|
212
|
+
|
|
213
|
+
```svelte
|
|
214
|
+
<!-- Input variants -->
|
|
215
|
+
<Input variant="default" label="Default Input" />
|
|
216
|
+
<Input variant="success" label="Success Input" />
|
|
217
|
+
<Input variant="warning" label="Warning Input" />
|
|
218
|
+
<Input variant="error" label="Error Input" />
|
|
219
|
+
|
|
220
|
+
<!-- Textarea variants -->
|
|
221
|
+
<Textarea variant="default" label="Default Textarea" />
|
|
222
|
+
<Textarea variant="success" label="Success Textarea" />
|
|
223
|
+
|
|
224
|
+
<!-- Card variants -->
|
|
225
|
+
<Card variant="default" title="Default Card" />
|
|
226
|
+
<Card variant="success" title="Success Card" />
|
|
227
|
+
<Card variant="warning" title="Warning Card" />
|
|
228
|
+
<Card variant="error" title="Error Card" />
|
|
229
|
+
<Card variant="info" title="Info Card" />
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### Utility Functions
|
|
233
|
+
|
|
234
|
+
For custom components or advanced usage, you can use the built-in utility functions:
|
|
235
|
+
|
|
236
|
+
```typescript
|
|
237
|
+
import {
|
|
238
|
+
getInputVariantClasses,
|
|
239
|
+
getCardVariantClasses,
|
|
240
|
+
getVariantClasses
|
|
241
|
+
} from 'zabi-components';
|
|
242
|
+
|
|
243
|
+
// For input components (Input, Textarea)
|
|
244
|
+
const inputClass = getInputVariantClasses('success'); // Returns "input-variant-success"
|
|
245
|
+
|
|
246
|
+
// For card components
|
|
247
|
+
const cardClass = getCardVariantClasses('error'); // Returns "card-variant-error"
|
|
248
|
+
|
|
249
|
+
// For custom components
|
|
250
|
+
const borderClass = getVariantClasses('warning', 'border'); // Returns "variant-border-warning"
|
|
251
|
+
const textClass = getVariantClasses('success', 'text'); // Returns "variant-text-success"
|
|
252
|
+
const bgClass = getVariantClasses('info', 'bg'); // Returns "variant-bg-info"
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### Dark Mode Support
|
|
256
|
+
|
|
257
|
+
The semantic color system automatically adapts to dark mode through CSS custom properties. Simply add the `.dark` class to your document:
|
|
258
|
+
|
|
259
|
+
```javascript
|
|
260
|
+
// Toggle dark mode
|
|
261
|
+
document.documentElement.classList.toggle('dark');
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
All components will automatically switch to their dark mode variants without any additional configuration.
|
|
265
|
+
|
|
148
266
|
## Component API
|
|
149
267
|
|
|
150
268
|
### Card Component
|
|
@@ -152,11 +270,10 @@ import type { ButtonEvents, InputEvents } from 'zabi-components/types';
|
|
|
152
270
|
```svelte
|
|
153
271
|
<Card
|
|
154
272
|
title={string}
|
|
155
|
-
subtitle={string}
|
|
156
|
-
description={string}
|
|
157
273
|
image={string}
|
|
158
|
-
variant="default" | "elevated"
|
|
159
274
|
interactive={boolean}
|
|
275
|
+
variant="default" | "success" | "warning" | "error" | "info"
|
|
276
|
+
size="sm" | "md" | "lg"
|
|
160
277
|
className={string}
|
|
161
278
|
on:click={(e) => console.log(e.detail.event)}
|
|
162
279
|
>
|
|
@@ -166,11 +283,10 @@ import type { ButtonEvents, InputEvents } from 'zabi-components/types';
|
|
|
166
283
|
|
|
167
284
|
**Props:**
|
|
168
285
|
- `title`: Card title
|
|
169
|
-
- `subtitle`: Card subtitle
|
|
170
|
-
- `description`: Card description
|
|
171
286
|
- `image`: Card image URL
|
|
172
|
-
- `variant`: Card style variant (default: "default")
|
|
173
287
|
- `interactive`: Make card clickable (default: false)
|
|
288
|
+
- `variant`: Card variant with semantic colors (default: "default")
|
|
289
|
+
- `size`: Card size (default: "md")
|
|
174
290
|
- `className`: Additional CSS classes
|
|
175
291
|
|
|
176
292
|
**Events:**
|
|
@@ -183,7 +299,7 @@ import type { ButtonEvents, InputEvents } from 'zabi-components/types';
|
|
|
183
299
|
method="get" | "post"
|
|
184
300
|
action={string}
|
|
185
301
|
className={string}
|
|
186
|
-
on:submit={(e) => console.log(
|
|
302
|
+
on:submit={(e) => console.log('Form submitted')}
|
|
187
303
|
>
|
|
188
304
|
<div class="form-field">
|
|
189
305
|
<label for="field" class="form-label">Label</label>
|
|
@@ -201,7 +317,7 @@ import type { ButtonEvents, InputEvents } from 'zabi-components/types';
|
|
|
201
317
|
- `className`: Additional CSS classes
|
|
202
318
|
|
|
203
319
|
**Events:**
|
|
204
|
-
- `submit`:
|
|
320
|
+
- `submit`: Native form submit event - use `FormData` to get form data
|
|
205
321
|
|
|
206
322
|
**CSS Classes:**
|
|
207
323
|
- `.form-field`: Field container
|
|
@@ -239,7 +355,7 @@ import type { ButtonEvents, InputEvents } from 'zabi-components/types';
|
|
|
239
355
|
items={Array<{label: string, href: string, icon?: any}>}
|
|
240
356
|
currentPath={string}
|
|
241
357
|
className={string}
|
|
242
|
-
on:
|
|
358
|
+
on:click={(e) => console.log('Navigation clicked')}
|
|
243
359
|
/>
|
|
244
360
|
```
|
|
245
361
|
|
|
@@ -250,7 +366,7 @@ import type { ButtonEvents, InputEvents } from 'zabi-components/types';
|
|
|
250
366
|
- `className`: Additional CSS classes
|
|
251
367
|
|
|
252
368
|
**Events:**
|
|
253
|
-
- `
|
|
369
|
+
- `click`: Native click event on navigation items
|
|
254
370
|
|
|
255
371
|
### Button Component
|
|
256
372
|
|
|
@@ -262,7 +378,7 @@ import type { ButtonEvents, InputEvents } from 'zabi-components/types';
|
|
|
262
378
|
loading={boolean}
|
|
263
379
|
type="button" | "submit" | "reset"
|
|
264
380
|
className={string}
|
|
265
|
-
on:click={(e) => console.log(
|
|
381
|
+
on:click={(e) => console.log('Button clicked')}
|
|
266
382
|
>
|
|
267
383
|
Button Content
|
|
268
384
|
</Button>
|
|
@@ -277,48 +393,69 @@ import type { ButtonEvents, InputEvents } from 'zabi-components/types';
|
|
|
277
393
|
- `className`: Additional CSS classes
|
|
278
394
|
|
|
279
395
|
**Events:**
|
|
280
|
-
- `click`:
|
|
396
|
+
- `click`: Native click event - `MouseEvent`
|
|
281
397
|
|
|
282
398
|
### Input Component
|
|
283
399
|
|
|
284
400
|
```svelte
|
|
285
401
|
<Input
|
|
286
|
-
|
|
402
|
+
value={string}
|
|
287
403
|
type={string}
|
|
288
404
|
label={string}
|
|
289
405
|
placeholder={string}
|
|
290
|
-
required={boolean}
|
|
291
406
|
disabled={boolean}
|
|
292
407
|
size="sm" | "md" | "lg"
|
|
293
|
-
variant="default" | "
|
|
294
|
-
error={string}
|
|
295
|
-
success={string}
|
|
296
|
-
helpText={string}
|
|
408
|
+
variant="default" | "success" | "warning" | "error"
|
|
297
409
|
className={string}
|
|
298
|
-
|
|
299
|
-
on:
|
|
300
|
-
on:change={(e) => console.log(e.detail.value, e.detail.event)}
|
|
410
|
+
on:input={(e) => console.log('Input changed:', e.target.value)}
|
|
411
|
+
on:change={(e) => console.log('Input changed:', e.target.value)}
|
|
301
412
|
/>
|
|
302
413
|
```
|
|
303
414
|
|
|
304
415
|
**Props:**
|
|
305
|
-
- `value`: Input value (
|
|
416
|
+
- `value`: Input value (controlled)
|
|
306
417
|
- `type`: Input type (default: "text")
|
|
307
418
|
- `label`: Input label
|
|
308
419
|
- `placeholder`: Input placeholder
|
|
309
|
-
- `required`: Mark as required (default: false)
|
|
310
420
|
- `disabled`: Disable the input (default: false)
|
|
311
421
|
- `size`: Input size (default: "md")
|
|
312
|
-
- `variant`: Input variant (default: "default")
|
|
313
|
-
- `error`: Error message
|
|
314
|
-
- `success`: Success message
|
|
315
|
-
- `helpText`: Helper text
|
|
422
|
+
- `variant`: Input variant with semantic colors (default: "default")
|
|
316
423
|
- `className`: Additional CSS classes
|
|
317
|
-
- `id`: Input ID
|
|
318
424
|
|
|
319
425
|
**Events:**
|
|
320
|
-
- `input`:
|
|
321
|
-
- `change`:
|
|
426
|
+
- `input`: Native input event - `InputEvent`
|
|
427
|
+
- `change`: Native change event - `Event`
|
|
428
|
+
|
|
429
|
+
### Textarea Component
|
|
430
|
+
|
|
431
|
+
```svelte
|
|
432
|
+
<Textarea
|
|
433
|
+
value={string}
|
|
434
|
+
label={string}
|
|
435
|
+
placeholder={string}
|
|
436
|
+
disabled={boolean}
|
|
437
|
+
rows={number}
|
|
438
|
+
size="sm" | "md" | "lg"
|
|
439
|
+
variant="default" | "success" | "warning" | "error"
|
|
440
|
+
className={string}
|
|
441
|
+
on:input={(e) => console.log('Textarea changed:', e.target.value)}
|
|
442
|
+
on:change={(e) => console.log('Textarea changed:', e.target.value)}
|
|
443
|
+
/>
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
**Props:**
|
|
447
|
+
- `value`: Textarea value (controlled)
|
|
448
|
+
- `label`: Textarea label
|
|
449
|
+
- `placeholder`: Textarea placeholder
|
|
450
|
+
- `disabled`: Disable the textarea (default: false)
|
|
451
|
+
- `rows`: Number of visible text lines (default: 4)
|
|
452
|
+
- `size`: Textarea size (default: "md")
|
|
453
|
+
- `variant`: Textarea variant with semantic colors (default: "default")
|
|
454
|
+
- `className`: Additional CSS classes
|
|
455
|
+
|
|
456
|
+
**Events:**
|
|
457
|
+
- `input`: Native input event - `InputEvent`
|
|
458
|
+
- `change`: Native change event - `Event`
|
|
322
459
|
|
|
323
460
|
### Card Component
|
|
324
461
|
|
|
@@ -489,127 +626,125 @@ Dark mode is automatically supported through CSS custom properties:
|
|
|
489
626
|
}
|
|
490
627
|
```
|
|
491
628
|
|
|
492
|
-
## Event
|
|
493
|
-
|
|
494
|
-
All components follow a consistent event structure:
|
|
629
|
+
## Event Handling
|
|
495
630
|
|
|
496
|
-
|
|
497
|
-
interface BaseEventDetail<T = any> {
|
|
498
|
-
value: T;
|
|
499
|
-
event?: Event;
|
|
500
|
-
}
|
|
501
|
-
```
|
|
631
|
+
Zabi Components now use **native DOM events** with **event forwarding** for maximum compatibility across frameworks.
|
|
502
632
|
|
|
503
|
-
|
|
504
|
-
- Button click: `{ detail: { value: true, event: MouseEvent } }`
|
|
505
|
-
- Input change: `{ detail: { value: string, event: Event } }`
|
|
506
|
-
- Checkbox change: `{ detail: { value: boolean, event: Event } }`
|
|
633
|
+
### Event Forwarding
|
|
507
634
|
|
|
508
|
-
|
|
635
|
+
All components use `{...$$restProps}` to forward native DOM events, making them compatible with React, Vue, Svelte, and vanilla JavaScript.
|
|
509
636
|
|
|
510
|
-
|
|
637
|
+
```svelte
|
|
638
|
+
<!-- All these work the same way -->
|
|
639
|
+
<Button on:click={handleClick}>Click me</Button>
|
|
640
|
+
<Input on:input={handleInput} on:change={handleChange} />
|
|
641
|
+
<Modal on:click={handleClose} on:keydown={handleKeydown} />
|
|
642
|
+
```
|
|
511
643
|
|
|
512
|
-
###
|
|
513
|
-
```typescript
|
|
514
|
-
import type {
|
|
515
|
-
ButtonEvents,
|
|
516
|
-
InputEvents,
|
|
517
|
-
CardEvents,
|
|
518
|
-
FormEvents,
|
|
519
|
-
NavigationEvents,
|
|
520
|
-
KeyValueFormEvents
|
|
521
|
-
} from 'zabi-components';
|
|
644
|
+
### Form Components
|
|
522
645
|
|
|
523
|
-
|
|
524
|
-
function handleButtonClick(event: CustomEvent<{ value: boolean; event?: MouseEvent }>) {
|
|
525
|
-
console.log('Button clicked:', event.detail.value);
|
|
526
|
-
}
|
|
646
|
+
Form components use **controlled components** pattern instead of two-way binding:
|
|
527
647
|
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
648
|
+
```svelte
|
|
649
|
+
<script lang="ts">
|
|
650
|
+
let inputValue = '';
|
|
651
|
+
let checkboxValue = false;
|
|
652
|
+
|
|
653
|
+
function handleInput(event: Event) {
|
|
654
|
+
inputValue = (event.target as HTMLInputElement).value;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
function handleCheckbox(event: Event) {
|
|
658
|
+
checkboxValue = (event.target as HTMLInputElement).checked;
|
|
659
|
+
}
|
|
660
|
+
</script>
|
|
534
661
|
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
662
|
+
<Input
|
|
663
|
+
value={inputValue}
|
|
664
|
+
on:input={handleInput}
|
|
665
|
+
label="Name"
|
|
666
|
+
/>
|
|
667
|
+
<Checkbox
|
|
668
|
+
checked={checkboxValue}
|
|
669
|
+
on:change={handleCheckbox}
|
|
670
|
+
label="Subscribe"
|
|
671
|
+
/>
|
|
541
672
|
```
|
|
542
673
|
|
|
543
|
-
###
|
|
544
|
-
```typescript
|
|
545
|
-
// All components have proper prop typing
|
|
546
|
-
interface CardProps {
|
|
547
|
-
title?: string;
|
|
548
|
-
subtitle?: string;
|
|
549
|
-
description?: string;
|
|
550
|
-
image?: string;
|
|
551
|
-
variant?: "default" | "elevated";
|
|
552
|
-
interactive?: boolean;
|
|
553
|
-
className?: string;
|
|
554
|
-
}
|
|
674
|
+
### Migration from Previous Versions
|
|
555
675
|
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
}
|
|
676
|
+
**Before (v2.0.x):**
|
|
677
|
+
```svelte
|
|
678
|
+
<Input bind:value={inputValue} />
|
|
679
|
+
<Button on:click={handleClick}>Click</Button>
|
|
680
|
+
<Modal bind:isOpen on:close={handleClose} />
|
|
561
681
|
```
|
|
562
682
|
|
|
563
|
-
|
|
564
|
-
```
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
submit: { data: Record<string, FormDataEntryValue>; formData: FormData };
|
|
569
|
-
navigate: { item: NavigationItem; href: string };
|
|
570
|
-
}>();
|
|
683
|
+
**After (v2.1.x):**
|
|
684
|
+
```svelte
|
|
685
|
+
<Input value={inputValue} on:input={(e) => inputValue = e.target.value} />
|
|
686
|
+
<Button on:click={handleClick}>Click</Button>
|
|
687
|
+
<Modal bind:isOpen on:click={handleClose} />
|
|
571
688
|
```
|
|
572
689
|
|
|
690
|
+
### Benefits
|
|
691
|
+
|
|
692
|
+
- ✅ **SSR Safe**: No more hydration errors in production
|
|
693
|
+
- ✅ **Cross-Framework**: Works in React, Vue, Svelte, vanilla JS
|
|
694
|
+
- ✅ **Standards Compliant**: Uses native DOM events
|
|
695
|
+
- ✅ **Better Performance**: Reduced JavaScript overhead
|
|
696
|
+
|
|
697
|
+
## TypeScript Support
|
|
698
|
+
|
|
699
|
+
Full TypeScript definitions are included with comprehensive type safety:
|
|
700
|
+
|
|
573
701
|
### Event Types
|
|
574
702
|
|
|
575
|
-
All components use
|
|
703
|
+
All components now use native DOM events with proper TypeScript typing:
|
|
576
704
|
|
|
577
705
|
```typescript
|
|
578
|
-
//
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
event?: Event;
|
|
706
|
+
// Native event handlers with proper typing
|
|
707
|
+
function handleButtonClick(event: MouseEvent) {
|
|
708
|
+
console.log('Button clicked:', event);
|
|
582
709
|
}
|
|
583
710
|
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
711
|
+
function handleInputChange(event: Event) {
|
|
712
|
+
const target = event.target as HTMLInputElement;
|
|
713
|
+
console.log('Input value:', target.value);
|
|
587
714
|
}
|
|
588
715
|
|
|
589
|
-
|
|
590
|
-
event
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
interface ChangeEventDetail extends BaseEventDetail<string> {
|
|
594
|
-
event?: Event;
|
|
716
|
+
function handleFormSubmit(event: SubmitEvent) {
|
|
717
|
+
const formData = new FormData(event.target as HTMLFormElement);
|
|
718
|
+
const data = Object.fromEntries(formData.entries());
|
|
719
|
+
console.log('Form data:', data);
|
|
595
720
|
}
|
|
596
721
|
```
|
|
597
722
|
|
|
598
|
-
### Component
|
|
723
|
+
### Component Props
|
|
724
|
+
|
|
725
|
+
All components have proper prop typing with event forwarding:
|
|
599
726
|
|
|
600
727
|
```typescript
|
|
601
|
-
|
|
602
|
-
|
|
728
|
+
// All components support event forwarding
|
|
729
|
+
interface ButtonProps {
|
|
730
|
+
variant?: "primary" | "secondary" | "danger";
|
|
731
|
+
size?: "sm" | "md" | "lg";
|
|
732
|
+
disabled?: boolean;
|
|
733
|
+
type?: "button" | "submit" | "reset";
|
|
734
|
+
className?: string;
|
|
735
|
+
// All native button events are forwarded via {...$$restProps}
|
|
603
736
|
}
|
|
604
737
|
|
|
605
|
-
interface
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
738
|
+
interface InputProps {
|
|
739
|
+
value?: string;
|
|
740
|
+
type?: string;
|
|
741
|
+
label?: string;
|
|
742
|
+
placeholder?: string;
|
|
743
|
+
disabled?: boolean;
|
|
744
|
+
size?: "sm" | "md" | "lg";
|
|
745
|
+
variant?: "default" | "success" | "warning" | "error";
|
|
746
|
+
className?: string;
|
|
747
|
+
// All native input events are forwarded via {...$$restProps}
|
|
613
748
|
}
|
|
614
749
|
```
|
|
615
750
|
|
|
@@ -622,7 +757,7 @@ interface InputEvents {
|
|
|
622
757
|
variant="primary"
|
|
623
758
|
size="lg"
|
|
624
759
|
className="w-full shadow-lg hover:shadow-xl"
|
|
625
|
-
on:click={(e) => console.log('Clicked!', e
|
|
760
|
+
on:click={(e) => console.log('Clicked!', e)}
|
|
626
761
|
>
|
|
627
762
|
Custom Button
|
|
628
763
|
</Button>
|
|
@@ -662,7 +797,7 @@ interface InputEvents {
|
|
|
662
797
|
return Object.keys(errors).length === 0;
|
|
663
798
|
}
|
|
664
799
|
|
|
665
|
-
function handleSubmit(event:
|
|
800
|
+
function handleSubmit(event: SubmitEvent) {
|
|
666
801
|
if (validateForm()) {
|
|
667
802
|
showSuccess = true;
|
|
668
803
|
// Submit form
|
|
@@ -678,27 +813,27 @@ interface InputEvents {
|
|
|
678
813
|
|
|
679
814
|
<form on:submit|preventDefault={handleSubmit}>
|
|
680
815
|
<Input
|
|
681
|
-
|
|
816
|
+
value={formData.name}
|
|
817
|
+
on:input={(e) => formData.name = e.target.value}
|
|
682
818
|
label="Name"
|
|
683
819
|
placeholder="Enter your name"
|
|
684
820
|
required
|
|
685
|
-
error={errors.name}
|
|
686
821
|
/>
|
|
687
822
|
|
|
688
823
|
<Input
|
|
689
|
-
|
|
824
|
+
value={formData.email}
|
|
690
825
|
type="email"
|
|
826
|
+
on:input={(e) => formData.email = e.target.value}
|
|
691
827
|
label="Email"
|
|
692
828
|
placeholder="Enter your email"
|
|
693
829
|
required
|
|
694
|
-
error={errors.email}
|
|
695
830
|
/>
|
|
696
831
|
|
|
697
832
|
<Input
|
|
698
|
-
|
|
833
|
+
value={formData.message}
|
|
834
|
+
on:input={(e) => formData.message = e.target.value}
|
|
699
835
|
label="Message"
|
|
700
836
|
placeholder="Enter your message"
|
|
701
|
-
helpText="Tell us what you think"
|
|
702
837
|
/>
|
|
703
838
|
|
|
704
839
|
<Button type="submit" variant="primary">
|
|
@@ -707,9 +842,11 @@ interface InputEvents {
|
|
|
707
842
|
</form>
|
|
708
843
|
|
|
709
844
|
<div slot="footer">
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
845
|
+
{#if showSuccess}
|
|
846
|
+
<Alert variant="success" closable>
|
|
847
|
+
Message sent successfully!
|
|
848
|
+
</Alert>
|
|
849
|
+
{/if}
|
|
713
850
|
</div>
|
|
714
851
|
</Card>
|
|
715
852
|
```
|
|
@@ -728,50 +865,32 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
|
|
|
728
865
|
|
|
729
866
|
## Changelog
|
|
730
867
|
|
|
731
|
-
###
|
|
732
|
-
|
|
733
|
-
####
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
- **
|
|
741
|
-
- **
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
- **
|
|
746
|
-
- **
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
#### 🚀 Modern CSS Features
|
|
758
|
-
- **Container Queries**: Added support for container-based responsive design
|
|
759
|
-
- **CSS Grid & Subgrid**: Implemented modern grid layouts
|
|
760
|
-
- **CSS Logical Properties**: Added RTL support with logical properties
|
|
761
|
-
- **CSS Cascade Layers**: Organized styles with cascade layers
|
|
762
|
-
- **CSS Containment**: Added performance optimizations
|
|
763
|
-
|
|
764
|
-
#### 📦 TypeScript Improvements
|
|
765
|
-
- **Event Type Safety**: All components now have proper event typing
|
|
766
|
-
- **Component Props**: Comprehensive prop type definitions
|
|
767
|
-
- **Event Dispatchers**: Typed event dispatchers for all components
|
|
768
|
-
- **Type Generation**: Proper TypeScript declaration generation
|
|
769
|
-
|
|
770
|
-
#### 🎨 Design System
|
|
771
|
-
- **Semantic HTML**: All components use proper semantic elements
|
|
772
|
-
- **Accessibility**: ARIA compliant with keyboard navigation
|
|
773
|
-
- **Dark Mode**: Built-in dark mode support with CSS custom properties
|
|
774
|
-
- **Responsive**: Mobile-first responsive design
|
|
868
|
+
### v2.1.0 (Latest) - "Cross-Framework Compatible" Edition
|
|
869
|
+
|
|
870
|
+
#### 🚀 **MAJOR BREAKING CHANGES** - Event Handling Overhaul
|
|
871
|
+
|
|
872
|
+
This is a **major breaking change** that affects how all components handle events. The refactoring eliminates SSR/production errors and makes components compatible with React, Vue, and vanilla JavaScript applications.
|
|
873
|
+
|
|
874
|
+
#### ✅ **What's Fixed**
|
|
875
|
+
- **SSR/Production Errors**: Eliminated all `createEventDispatcher` hydration errors
|
|
876
|
+
- **Cross-Framework Compatibility**: Components now work in React, Vue, Svelte, and vanilla JS
|
|
877
|
+
- **Event Forwarding**: All components use `{...$$restProps}` for native DOM events
|
|
878
|
+
- **Standards Compliance**: Uses web standards instead of framework-specific events
|
|
879
|
+
|
|
880
|
+
#### 🔄 **Migration Required**
|
|
881
|
+
- **Form Components**: Replace `bind:value` with `value` prop + event handlers
|
|
882
|
+
- **Event Names**: Some custom events replaced with native DOM events
|
|
883
|
+
- **Event Structure**: Simplified event structures across all components
|
|
884
|
+
|
|
885
|
+
#### 📋 **Breaking Changes**
|
|
886
|
+
1. **Form Components**: Must use `value` prop + event handlers instead of `bind:value`
|
|
887
|
+
2. **Event Names**: Some custom events replaced with native DOM events
|
|
888
|
+
3. **Event Structure**: Simplified event structures across all components
|
|
889
|
+
4. **SSR Compatibility**: Components now work correctly in SSR environments
|
|
890
|
+
|
|
891
|
+
See the [Migration Guide](#migration-from-previous-versions) above for detailed examples.
|
|
892
|
+
|
|
893
|
+
### v2.0.2 - "Less is More" Edition
|
|
775
894
|
|
|
776
895
|
## Development Setup
|
|
777
896
|
|