zabi-components 5.0.20 → 5.0.21
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/LICENSE +21 -0
- package/README.md +354 -81
- package/dist/atoms/Button.svelte +1 -1
- package/dist/atoms/IconButton.svelte +88 -0
- package/dist/atoms/IconButton.svelte.d.ts +21 -0
- package/dist/atoms/Select.svelte +96 -6
- package/dist/atoms/Select.svelte.d.ts +10 -0
- package/dist/atoms/index.d.ts +1 -0
- package/dist/atoms/index.js +1 -0
- package/dist/components/atoms/index.d.ts +1 -0
- package/dist/components/atoms/index.d.ts.map +1 -1
- package/dist/components/molecules/index.d.ts +1 -0
- package/dist/components/molecules/index.d.ts.map +1 -1
- package/dist/molecules/Section.svelte +158 -0
- package/dist/molecules/Section.svelte.d.ts +27 -0
- package/dist/molecules/index.d.ts +1 -0
- package/dist/molecules/index.js +1 -0
- package/dist/organisms/Navigation.svelte +2 -2
- package/dist/zabi-components.css +110 -0
- package/package.json +3 -5
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Zabi Components Team
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
A clean, minimal Svelte 5 component library built with TypeScript and Tailwind CSS. **Less is more** - focused on essential components that just work.
|
|
4
4
|
|
|
5
|
-
> **⚠️ Svelte 5 Required**: This library uses Svelte 5 runes syntax (`$props`, `$derived`, `$state`). Make sure you're using Svelte 5.
|
|
5
|
+
> **⚠️ Svelte 5 Required**: This library uses Svelte 5 runes syntax (`$props`, `$derived`, `$state`). Make sure you're using Svelte 5.43.8 or later.
|
|
6
6
|
|
|
7
7
|
## Philosophy
|
|
8
8
|
|
|
@@ -36,7 +36,7 @@ npm install zabi-components
|
|
|
36
36
|
Make sure you have the required peer dependencies installed:
|
|
37
37
|
|
|
38
38
|
```bash
|
|
39
|
-
npm install svelte@^5.
|
|
39
|
+
npm install svelte@^5.43.8
|
|
40
40
|
npm install @sveltejs/kit@^2.0.0 # Optional, for SvelteKit projects
|
|
41
41
|
```
|
|
42
42
|
|
|
@@ -97,18 +97,65 @@ Zabi Components supports multiple import patterns:
|
|
|
97
97
|
|
|
98
98
|
### Main Import (All Components)
|
|
99
99
|
```typescript
|
|
100
|
-
import {
|
|
100
|
+
import {
|
|
101
|
+
Button,
|
|
102
|
+
IconButton,
|
|
103
|
+
Input,
|
|
104
|
+
Card,
|
|
105
|
+
CardHeader,
|
|
106
|
+
CardContent,
|
|
107
|
+
CardFooter,
|
|
108
|
+
Alert,
|
|
109
|
+
Badge,
|
|
110
|
+
Modal,
|
|
111
|
+
NavigationMenu,
|
|
112
|
+
Section
|
|
113
|
+
} from 'zabi-components';
|
|
101
114
|
```
|
|
102
115
|
|
|
103
116
|
### Subpath Imports (Recommended for Tree Shaking)
|
|
104
117
|
```typescript
|
|
105
118
|
// Import from specific categories
|
|
106
|
-
import {
|
|
107
|
-
|
|
108
|
-
|
|
119
|
+
import {
|
|
120
|
+
Button,
|
|
121
|
+
IconButton,
|
|
122
|
+
Input,
|
|
123
|
+
Badge,
|
|
124
|
+
Card,
|
|
125
|
+
CardHeader,
|
|
126
|
+
CardContent,
|
|
127
|
+
CardFooter
|
|
128
|
+
} from 'zabi-components/atoms';
|
|
129
|
+
import {
|
|
130
|
+
Alert,
|
|
131
|
+
Modal,
|
|
132
|
+
Dropdown,
|
|
133
|
+
NavigationMenu,
|
|
134
|
+
NavigationMenuList,
|
|
135
|
+
NavigationMenuItem,
|
|
136
|
+
NavigationMenuTrigger,
|
|
137
|
+
NavigationMenuContent,
|
|
138
|
+
NavigationMenuLink,
|
|
139
|
+
Section,
|
|
140
|
+
Tabs
|
|
141
|
+
} from 'zabi-components/molecules';
|
|
142
|
+
import {
|
|
143
|
+
Navbar,
|
|
144
|
+
Navigation
|
|
145
|
+
} from 'zabi-components/organisms';
|
|
109
146
|
|
|
110
147
|
// Import types separately
|
|
111
148
|
import type { ButtonEvents, InputEvents } from 'zabi-components/types';
|
|
149
|
+
|
|
150
|
+
// Import utility functions
|
|
151
|
+
import {
|
|
152
|
+
createId,
|
|
153
|
+
cn,
|
|
154
|
+
getFormData,
|
|
155
|
+
validateEmail,
|
|
156
|
+
safeLocalStorage,
|
|
157
|
+
safeDocument
|
|
158
|
+
} from 'zabi-components';
|
|
112
159
|
```
|
|
113
160
|
|
|
114
161
|
## Quick Start
|
|
@@ -116,7 +163,20 @@ import type { ButtonEvents, InputEvents } from 'zabi-components/types';
|
|
|
116
163
|
```svelte
|
|
117
164
|
<script lang="ts">
|
|
118
165
|
// Clean Components - Less is More
|
|
119
|
-
import {
|
|
166
|
+
import {
|
|
167
|
+
Card,
|
|
168
|
+
CardHeader,
|
|
169
|
+
CardContent,
|
|
170
|
+
CardFooter,
|
|
171
|
+
Form,
|
|
172
|
+
Navigation,
|
|
173
|
+
Button,
|
|
174
|
+
IconButton,
|
|
175
|
+
Input,
|
|
176
|
+
Textarea,
|
|
177
|
+
Badge,
|
|
178
|
+
Alert
|
|
179
|
+
} from 'zabi-components';
|
|
120
180
|
|
|
121
181
|
let formData = $state({
|
|
122
182
|
name: '',
|
|
@@ -141,76 +201,115 @@ import type { ButtonEvents, InputEvents } from 'zabi-components/types';
|
|
|
141
201
|
];
|
|
142
202
|
</script>
|
|
143
203
|
|
|
144
|
-
<
|
|
145
|
-
<
|
|
204
|
+
<div class="min-h-screen bg-gray-50">
|
|
205
|
+
<header class="flex items-center justify-between p-4 bg-white border-b">
|
|
146
206
|
<h1 class="text-xl font-bold">My App</h1>
|
|
147
207
|
<Navigation variant="header" items={navItems} />
|
|
148
|
-
</
|
|
208
|
+
</header>
|
|
149
209
|
|
|
150
210
|
<main class="container mx-auto p-6">
|
|
151
|
-
<!--
|
|
211
|
+
<!-- Card with Compound Components -->
|
|
152
212
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 mb-8">
|
|
153
|
-
<Card
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
213
|
+
<Card variant="elevated" onclick={handleCardClick}>
|
|
214
|
+
<CardHeader>
|
|
215
|
+
<h3 class="text-lg font-semibold">Default Card</h3>
|
|
216
|
+
</CardHeader>
|
|
217
|
+
<CardContent>
|
|
218
|
+
<p>This is a card using compound components.</p>
|
|
219
|
+
</CardContent>
|
|
220
|
+
<CardFooter>
|
|
221
|
+
<Button variant="primary" size="sm">Learn More</Button>
|
|
222
|
+
</CardFooter>
|
|
158
223
|
</Card>
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
224
|
+
|
|
225
|
+
<Card variant="success" onclick={handleCardClick}>
|
|
226
|
+
<CardHeader>
|
|
227
|
+
<h3 class="text-lg font-semibold">Success Card</h3>
|
|
228
|
+
</CardHeader>
|
|
229
|
+
<CardContent>
|
|
230
|
+
<p>This card indicates a successful action.</p>
|
|
231
|
+
</CardContent>
|
|
164
232
|
</Card>
|
|
165
|
-
|
|
166
|
-
|
|
233
|
+
|
|
234
|
+
<Card variant="warning" onclick={handleCardClick}>
|
|
235
|
+
<CardHeader>
|
|
236
|
+
<h3 class="text-lg font-semibold">Warning Card</h3>
|
|
237
|
+
</CardHeader>
|
|
238
|
+
<CardContent>
|
|
239
|
+
<p>This card shows a warning state.</p>
|
|
240
|
+
</CardContent>
|
|
167
241
|
</Card>
|
|
168
242
|
</div>
|
|
169
243
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
244
|
+
<!-- Form with Semantic Variants -->
|
|
245
|
+
<Card variant="outlined">
|
|
246
|
+
<CardHeader>
|
|
247
|
+
<h2 class="text-xl font-bold">Contact Form</h2>
|
|
248
|
+
</CardHeader>
|
|
249
|
+
<CardContent>
|
|
250
|
+
<Form onsubmit={handleFormSubmit}>
|
|
251
|
+
<div class="form-field">
|
|
252
|
+
<Input
|
|
253
|
+
id="name"
|
|
254
|
+
name="name"
|
|
255
|
+
value={formData.name}
|
|
256
|
+
oninput={(e) => formData.name = (e.target as HTMLInputElement).value}
|
|
257
|
+
label="Name"
|
|
258
|
+
placeholder="Enter your name"
|
|
259
|
+
variant="default"
|
|
260
|
+
/>
|
|
261
|
+
</div>
|
|
262
|
+
|
|
263
|
+
<div class="form-field">
|
|
264
|
+
<Input
|
|
265
|
+
id="email"
|
|
266
|
+
name="email"
|
|
267
|
+
type="email"
|
|
268
|
+
value={formData.email}
|
|
269
|
+
oninput={(e) => formData.email = (e.target as HTMLInputElement).value}
|
|
270
|
+
label="Email"
|
|
271
|
+
placeholder="Enter your email"
|
|
272
|
+
variant="success"
|
|
273
|
+
/>
|
|
274
|
+
</div>
|
|
275
|
+
|
|
276
|
+
<div class="form-field">
|
|
277
|
+
<Textarea
|
|
278
|
+
id="message"
|
|
279
|
+
name="message"
|
|
280
|
+
value={formData.message}
|
|
281
|
+
oninput={(e) => formData.message = (e.target as HTMLTextAreaElement).value}
|
|
282
|
+
label="Message"
|
|
283
|
+
placeholder="Enter your message"
|
|
284
|
+
variant="default"
|
|
285
|
+
/>
|
|
286
|
+
</div>
|
|
287
|
+
|
|
288
|
+
<div class="form-actions flex gap-2">
|
|
289
|
+
<Button type="submit" variant="primary" className="flex-1">
|
|
290
|
+
Submit
|
|
291
|
+
</Button>
|
|
292
|
+
<IconButton variant="outline" label="Help">
|
|
293
|
+
❓
|
|
294
|
+
</IconButton>
|
|
295
|
+
</div>
|
|
296
|
+
</Form>
|
|
297
|
+
</CardContent>
|
|
298
|
+
</Card>
|
|
299
|
+
|
|
300
|
+
<!-- Badges and Alerts -->
|
|
301
|
+
<div class="mt-6 space-y-4">
|
|
302
|
+
<div class="flex gap-2">
|
|
303
|
+
<Badge variant="success">Success</Badge>
|
|
304
|
+
<Badge variant="warning">Warning</Badge>
|
|
305
|
+
<Badge variant="error">Error</Badge>
|
|
306
|
+
<Badge variant="info">Info</Badge>
|
|
206
307
|
</div>
|
|
207
308
|
|
|
208
|
-
<
|
|
209
|
-
|
|
210
|
-
</div>
|
|
211
|
-
</Form>
|
|
309
|
+
<Alert variant="info" title="Information" message="This is an informational alert." />
|
|
310
|
+
</div>
|
|
212
311
|
</main>
|
|
213
|
-
</
|
|
312
|
+
</div>
|
|
214
313
|
```
|
|
215
314
|
|
|
216
315
|
## Component Overview
|
|
@@ -220,25 +319,31 @@ import type { ButtonEvents, InputEvents } from 'zabi-components/types';
|
|
|
220
319
|
| Component | Category | Description | Key Features |
|
|
221
320
|
|-----------|----------|-------------|--------------|
|
|
222
321
|
| **Card** | Atom | Clean card container | Simple, interactive, image support, compound components, 4 variants |
|
|
322
|
+
| **CardHeader** | Atom | Card header section | Compound component for card structure |
|
|
323
|
+
| **CardContent** | Atom | Card content section | Compound component for card structure |
|
|
324
|
+
| **CardFooter** | Atom | Card footer section | Compound component for card structure |
|
|
223
325
|
| **Form** | Molecule | Simple form wrapper | FormData handling, clean API |
|
|
224
|
-
| **Layout** | Molecule | Page layout system | Header, main, footer slots |
|
|
225
326
|
| **Navigation** | Organism | Clean navigation | Header/sidebar variants, active state |
|
|
226
327
|
| **Button** | Atom | Action button | 6 variants (primary, secondary, danger, ghost, outline, link) |
|
|
227
|
-
| **
|
|
228
|
-
| **
|
|
328
|
+
| **IconButton** | Atom | Icon-only button | Icon-only, variants, sizes, accessible label |
|
|
329
|
+
| **Input** | Atom | Form input | Essential props, accessibility, semantic variants |
|
|
330
|
+
| **Badge** | Atom | Status indicator | 5 color variants, closable, icon support |
|
|
229
331
|
| **Modal** | Molecule | Overlay dialog | Focus trap, keyboard navigation, focus return |
|
|
230
332
|
| **Tabs** | Molecule | Tab navigation | Keyboard navigation, 2 variants |
|
|
231
333
|
| **Dropdown** | Molecule | Dropdown menu | CSS-only positioning, keyboard navigation, ARIA support |
|
|
232
334
|
| **ImageUpload** | Molecule | File upload | Direct selection, preview |
|
|
233
335
|
| **Navbar** | Organism | Navigation bar | Mobile menu, responsive |
|
|
336
|
+
| **NavigationMenu** | Molecule | Advanced navigation menu | Compound components, keyboard navigation |
|
|
337
|
+
| **Section** | Molecule | Content section wrapper | Responsive layout, variant support |
|
|
338
|
+
| **Sidebar** | Molecule | Sidebar navigation | Collapsible, responsive |
|
|
234
339
|
|
|
235
340
|
### Simplified Components
|
|
236
341
|
|
|
237
342
|
| Component | Category | Description | Key Features |
|
|
238
343
|
|-----------|----------|-------------|--------------|
|
|
239
|
-
| **Checkbox** | Atom | Checkbox input | Simple on/off state |
|
|
240
|
-
| **Select** | Atom | Dropdown select | Basic options support |
|
|
241
|
-
| **Textarea** | Atom | Multi-line input | Essential configuration |
|
|
344
|
+
| **Checkbox** | Atom | Checkbox input | Simple on/off state, semantic variants |
|
|
345
|
+
| **Select** | Atom | Dropdown select | Basic options support, semantic variants |
|
|
346
|
+
| **Textarea** | Atom | Multi-line input | Essential configuration, semantic variants |
|
|
242
347
|
| **Toggle** | Atom | Toggle switch | Fixed size, simple state |
|
|
243
348
|
| **Progress** | Atom | Progress bar | Percentage display |
|
|
244
349
|
| **Heading** | Atom | Text headings | 6 levels, clean styling |
|
|
@@ -248,6 +353,12 @@ import type { ButtonEvents, InputEvents } from 'zabi-components/types';
|
|
|
248
353
|
| **Skeleton** | Atom | Loading placeholder | Simple animation |
|
|
249
354
|
| **ColorPicker** | Atom | Color selection | Simple color grid |
|
|
250
355
|
| **SlideUp** | Molecule | Slide-up panel | CSS-only animations |
|
|
356
|
+
| **CodeBlock** | Atom | Code display | Syntax highlighting support |
|
|
357
|
+
| **FeatureCard** | Atom | Feature showcase card | Image, title, description |
|
|
358
|
+
| **OptimizedImage** | Atom | Optimized image | Lazy loading, responsive |
|
|
359
|
+
| **Alert** | Molecule | Alert notification | Variants, closable, custom content |
|
|
360
|
+
| **ContactForm** | Molecule | Contact form | Pre-built form with validation |
|
|
361
|
+
| **ComponentDemo** | Molecule | Component showcase | Demo wrapper for examples |
|
|
251
362
|
|
|
252
363
|
## Semantic Color System
|
|
253
364
|
|
|
@@ -286,14 +397,68 @@ All components support these semantic color variants:
|
|
|
286
397
|
|
|
287
398
|
### Utility Functions
|
|
288
399
|
|
|
289
|
-
|
|
400
|
+
Zabi Components exports several utility functions for common tasks:
|
|
401
|
+
|
|
402
|
+
```typescript
|
|
403
|
+
// Main exports (most utilities)
|
|
404
|
+
import {
|
|
405
|
+
createId,
|
|
406
|
+
cn,
|
|
407
|
+
getFormData,
|
|
408
|
+
validateEmail,
|
|
409
|
+
validateRequired,
|
|
410
|
+
isBrowser,
|
|
411
|
+
safeWindow,
|
|
412
|
+
safeDocument,
|
|
413
|
+
safeLocalStorage,
|
|
414
|
+
generateId
|
|
415
|
+
} from 'zabi-components';
|
|
416
|
+
|
|
417
|
+
// Or import SSR-safe utilities directly
|
|
418
|
+
import {
|
|
419
|
+
safeLocalStorage,
|
|
420
|
+
safeDocument,
|
|
421
|
+
safeWindow,
|
|
422
|
+
isBrowser,
|
|
423
|
+
generateId
|
|
424
|
+
} from 'zabi-components/lib/ssr-safe';
|
|
425
|
+
|
|
426
|
+
// ID Generation (SSR-safe)
|
|
427
|
+
const uniqueId = createId('input'); // Returns "input-abc123xyz" (client) or "input-ssr-1234567890" (server)
|
|
428
|
+
|
|
429
|
+
// Class Name Utility
|
|
430
|
+
const className = cn('base-class', condition && 'conditional-class', undefined);
|
|
431
|
+
// Returns "base-class conditional-class" (filters out falsy values)
|
|
432
|
+
|
|
433
|
+
// Form Utilities
|
|
434
|
+
const form = document.querySelector('form') as HTMLFormElement;
|
|
435
|
+
const data = getFormData(form); // Returns object with form data
|
|
436
|
+
|
|
437
|
+
// Validation
|
|
438
|
+
const isValidEmail = validateEmail('user@example.com'); // Returns true/false
|
|
439
|
+
const isRequired = validateRequired('value'); // Returns true/false
|
|
440
|
+
|
|
441
|
+
// Browser Detection (SSR-safe)
|
|
442
|
+
if (isBrowser()) {
|
|
443
|
+
// Safe to use window, document, localStorage, etc.
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// Safe Browser APIs
|
|
447
|
+
const window = safeWindow(); // Returns Window | undefined
|
|
448
|
+
const document = safeDocument(); // Returns Document | undefined
|
|
449
|
+
const storage = safeLocalStorage(); // Returns Storage | undefined
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
### Variant Utility Functions
|
|
453
|
+
|
|
454
|
+
For custom components or advanced usage, you can use the built-in variant utility functions:
|
|
290
455
|
|
|
291
456
|
```typescript
|
|
292
457
|
import {
|
|
293
458
|
getInputVariantClasses,
|
|
294
459
|
getCardVariantClasses,
|
|
295
460
|
getVariantClasses
|
|
296
|
-
} from 'zabi-components';
|
|
461
|
+
} from 'zabi-components/lib/variant-utils';
|
|
297
462
|
|
|
298
463
|
// For input components (Input, Textarea)
|
|
299
464
|
const inputClass = getInputVariantClasses('success'); // Returns "input-variant-success"
|
|
@@ -423,11 +588,74 @@ All components will automatically switch to their dark mode variants without any
|
|
|
423
588
|
**Events:**
|
|
424
589
|
- `click`: Native click event on navigation items
|
|
425
590
|
|
|
591
|
+
### NavigationMenu Component
|
|
592
|
+
|
|
593
|
+
Advanced navigation menu system with compound components:
|
|
594
|
+
|
|
595
|
+
```svelte
|
|
596
|
+
<script lang="ts">
|
|
597
|
+
import {
|
|
598
|
+
NavigationMenu,
|
|
599
|
+
NavigationMenuList,
|
|
600
|
+
NavigationMenuItem,
|
|
601
|
+
NavigationMenuTrigger,
|
|
602
|
+
NavigationMenuContent,
|
|
603
|
+
NavigationMenuLink
|
|
604
|
+
} from 'zabi-components';
|
|
605
|
+
</script>
|
|
606
|
+
|
|
607
|
+
<NavigationMenu>
|
|
608
|
+
<NavigationMenuList>
|
|
609
|
+
<NavigationMenuItem>
|
|
610
|
+
<NavigationMenuTrigger>Products</NavigationMenuTrigger>
|
|
611
|
+
<NavigationMenuContent>
|
|
612
|
+
<NavigationMenuLink href="/products/web">Web</NavigationMenuLink>
|
|
613
|
+
<NavigationMenuLink href="/products/mobile">Mobile</NavigationMenuLink>
|
|
614
|
+
</NavigationMenuContent>
|
|
615
|
+
</NavigationMenuItem>
|
|
616
|
+
<NavigationMenuItem>
|
|
617
|
+
<NavigationMenuLink href="/about">About</NavigationMenuLink>
|
|
618
|
+
</NavigationMenuItem>
|
|
619
|
+
</NavigationMenuList>
|
|
620
|
+
</NavigationMenu>
|
|
621
|
+
```
|
|
622
|
+
|
|
623
|
+
**Compound Components:**
|
|
624
|
+
- `NavigationMenu`: Root container
|
|
625
|
+
- `NavigationMenuList`: List wrapper
|
|
626
|
+
- `NavigationMenuItem`: Individual menu item
|
|
627
|
+
- `NavigationMenuTrigger`: Trigger for dropdown items
|
|
628
|
+
- `NavigationMenuContent`: Dropdown content container
|
|
629
|
+
- `NavigationMenuLink`: Navigation link component
|
|
630
|
+
|
|
631
|
+
**Features:**
|
|
632
|
+
- Keyboard navigation support
|
|
633
|
+
- ARIA compliant
|
|
634
|
+
- CSS-only positioning
|
|
635
|
+
- Responsive design
|
|
636
|
+
|
|
637
|
+
### Section Component
|
|
638
|
+
|
|
639
|
+
```svelte
|
|
640
|
+
<Section
|
|
641
|
+
variant="default" | "primary" | "secondary"
|
|
642
|
+
size="sm" | "md" | "lg" | "xl"
|
|
643
|
+
className={string}
|
|
644
|
+
>
|
|
645
|
+
Section content
|
|
646
|
+
</Section>
|
|
647
|
+
```
|
|
648
|
+
|
|
649
|
+
**Props:**
|
|
650
|
+
- `variant`: Section style variant (default: "default")
|
|
651
|
+
- `size`: Section size (default: "md")
|
|
652
|
+
- `className`: Additional CSS classes
|
|
653
|
+
|
|
426
654
|
### Button Component
|
|
427
655
|
|
|
428
656
|
```svelte
|
|
429
657
|
<Button
|
|
430
|
-
variant="primary" | "secondary" | "danger" | "
|
|
658
|
+
variant="primary" | "secondary" | "danger" | "ghost" | "outline" | "link"
|
|
431
659
|
size="sm" | "md" | "lg"
|
|
432
660
|
disabled={boolean}
|
|
433
661
|
type="button" | "submit" | "reset"
|
|
@@ -440,6 +668,12 @@ All components will automatically switch to their dark mode variants without any
|
|
|
440
668
|
|
|
441
669
|
**Props:**
|
|
442
670
|
- `variant`: Button style variant (default: "primary")
|
|
671
|
+
- `primary`: Primary action button with solid background
|
|
672
|
+
- `secondary`: Secondary action button
|
|
673
|
+
- `danger`: Destructive action button (red)
|
|
674
|
+
- `ghost`: Transparent button with hover effect
|
|
675
|
+
- `outline`: Outlined button with border
|
|
676
|
+
- `link`: Text button styled as a link
|
|
443
677
|
- `size`: Button size (default: "md")
|
|
444
678
|
- `disabled`: Disable the button (default: false)
|
|
445
679
|
- `type`: HTML button type (default: "button")
|
|
@@ -448,6 +682,31 @@ All components will automatically switch to their dark mode variants without any
|
|
|
448
682
|
**Events:**
|
|
449
683
|
- `onclick`: Native click event - `MouseEvent`
|
|
450
684
|
|
|
685
|
+
### IconButton Component
|
|
686
|
+
|
|
687
|
+
```svelte
|
|
688
|
+
<IconButton
|
|
689
|
+
variant="primary" | "secondary" | "danger" | "ghost" | "outline" | "link"
|
|
690
|
+
size="sm" | "md" | "lg"
|
|
691
|
+
disabled={boolean}
|
|
692
|
+
type="button" | "submit" | "reset"
|
|
693
|
+
label={string}
|
|
694
|
+
onclick={(e) => console.log('Icon clicked', e)}
|
|
695
|
+
>
|
|
696
|
+
<!-- Icon content -->
|
|
697
|
+
</IconButton>
|
|
698
|
+
```
|
|
699
|
+
|
|
700
|
+
**Props:**
|
|
701
|
+
- `variant`: Icon button style (default: "primary")
|
|
702
|
+
- `size`: Icon button size (default: "md")
|
|
703
|
+
- `disabled`: Disable the button (default: false)
|
|
704
|
+
- `type`: HTML button type (default: "button")
|
|
705
|
+
- `label`: Accessible label for screen readers
|
|
706
|
+
|
|
707
|
+
**Events:**
|
|
708
|
+
- `onclick`: Native click event - `MouseEvent`
|
|
709
|
+
|
|
451
710
|
### Input Component
|
|
452
711
|
|
|
453
712
|
```svelte
|
|
@@ -812,7 +1071,7 @@ All components have proper prop typing with event forwarding:
|
|
|
812
1071
|
```typescript
|
|
813
1072
|
// All components support event forwarding
|
|
814
1073
|
interface ButtonProps {
|
|
815
|
-
variant?: "primary" | "secondary" | "danger";
|
|
1074
|
+
variant?: "primary" | "secondary" | "danger" | "ghost" | "outline" | "link";
|
|
816
1075
|
size?: "sm" | "md" | "lg";
|
|
817
1076
|
disabled?: boolean;
|
|
818
1077
|
type?: "button" | "submit" | "reset";
|
|
@@ -853,7 +1112,7 @@ Components use consistent SSR-safe patterns:
|
|
|
853
1112
|
```svelte
|
|
854
1113
|
<script lang="ts">
|
|
855
1114
|
import { onMount } from "svelte";
|
|
856
|
-
import { safeLocalStorage, safeDocument } from "zabi-components/ssr-safe";
|
|
1115
|
+
import { safeLocalStorage, safeDocument } from "zabi-components/lib/ssr-safe";
|
|
857
1116
|
|
|
858
1117
|
let mounted = $state(false);
|
|
859
1118
|
|
|
@@ -1016,7 +1275,21 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
|
|
|
1016
1275
|
|
|
1017
1276
|
## Changelog
|
|
1018
1277
|
|
|
1019
|
-
###
|
|
1278
|
+
### v5.0.21 (Latest) - Current Version
|
|
1279
|
+
|
|
1280
|
+
See [CHANGELOG.md](./CHANGELOG.md) for the complete changelog.
|
|
1281
|
+
|
|
1282
|
+
### v5.0.18 - "Enhanced Components" Edition
|
|
1283
|
+
|
|
1284
|
+
#### ✨ **Component Enhancements**
|
|
1285
|
+
- **Card Compound Components**: Added CardHeader, CardContent, CardFooter, CardTitle, and CardDescription
|
|
1286
|
+
- **Button Variants**: Added ghost, outline, and link variants
|
|
1287
|
+
- **Badge Updates**: Added icon support and enhanced size variants
|
|
1288
|
+
- **NavigationMenu**: Complete navigation menu system with compound components
|
|
1289
|
+
- **Section Component**: New responsive section wrapper component
|
|
1290
|
+
- **Accessibility**: Enhanced focus management and keyboard navigation across all components
|
|
1291
|
+
|
|
1292
|
+
### v4.0.0 - "Svelte 5 Runes" Edition
|
|
1020
1293
|
|
|
1021
1294
|
#### 🚀 **MAJOR UPDATE** - Svelte 5 Migration
|
|
1022
1295
|
|
|
@@ -1029,12 +1302,12 @@ This version migrates to Svelte 5 with runes syntax for better performance and d
|
|
|
1029
1302
|
- **Modern Syntax**: Cleaner, more intuitive component APIs
|
|
1030
1303
|
|
|
1031
1304
|
#### 🔄 **Migration Required**
|
|
1032
|
-
- **Svelte Version**: Requires Svelte 5.
|
|
1305
|
+
- **Svelte Version**: Requires Svelte 5.43.8 or later
|
|
1033
1306
|
- **Syntax Updates**: Components now use runes syntax
|
|
1034
1307
|
- **Event Handling**: Updated to use `oninput`, `onclick` instead of `on:input`, `on:click`
|
|
1035
1308
|
|
|
1036
1309
|
#### 📋 **Breaking Changes**
|
|
1037
|
-
1. **Svelte Version**: Must upgrade to Svelte 5.
|
|
1310
|
+
1. **Svelte Version**: Must upgrade to Svelte 5.43.8+
|
|
1038
1311
|
2. **Event Syntax**: Use `oninput`, `onclick` instead of `on:input`, `on:click`
|
|
1039
1312
|
3. **Component Props**: All components use Svelte 5 runes syntax
|
|
1040
1313
|
|
|
@@ -1070,12 +1343,12 @@ See the [Migration Guide](#migration-from-previous-versions) above for detailed
|
|
|
1070
1343
|
### Prerequisites
|
|
1071
1344
|
- Node.js 18+
|
|
1072
1345
|
- npm or yarn
|
|
1073
|
-
- Svelte 5.
|
|
1346
|
+
- Svelte 5.43.8+ or SvelteKit 2+
|
|
1074
1347
|
|
|
1075
1348
|
### Local Development
|
|
1076
1349
|
```bash
|
|
1077
1350
|
# Clone the repository
|
|
1078
|
-
git clone https://github.com/
|
|
1351
|
+
git clone https://github.com/sabnor/zabi-components.git
|
|
1079
1352
|
cd zabi-components
|
|
1080
1353
|
|
|
1081
1354
|
# Install dependencies
|
|
@@ -1157,7 +1430,7 @@ npm install zabi-components@latest
|
|
|
1157
1430
|
If you encounter runtime errors, ensure you have the correct peer dependencies:
|
|
1158
1431
|
|
|
1159
1432
|
```bash
|
|
1160
|
-
npm install svelte@^5.
|
|
1433
|
+
npm install svelte@^5.43.8 @sveltejs/kit@^2.0.0
|
|
1161
1434
|
```
|
|
1162
1435
|
|
|
1163
1436
|
### Migration from Previous Versions
|
package/dist/atoms/Button.svelte
CHANGED
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
const sizeStyles = sizeClass();
|
|
80
80
|
const flexClass = isFullWidth ? "flex" : "inline-flex";
|
|
81
81
|
const widthClass = isFullWidth ? "w-full" : "";
|
|
82
|
-
const baseClasses = `${flexClass} items-center justify-center transition-all duration-200 cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed
|
|
82
|
+
const baseClasses = `${flexClass} items-center justify-center transition-all duration-200 cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed focus:outline-none`;
|
|
83
83
|
|
|
84
84
|
return `${baseClasses} ${widthClass} ${sizeStyles.padding} ${sizeStyles.text} ${sizeStyles.font} ${sizeStyles.leading} ${sizeStyles.tracking} ${sizeStyles.radius} ${sizeStyles.gap} ${variantClass()}`.trim();
|
|
85
85
|
});
|