@velkymx/vibeui 0.5.4 → 0.6.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 CHANGED
@@ -5,30 +5,25 @@ A modern Vue 3 UI component library built with Bootstrap 5, designed to simplify
5
5
  ## Features
6
6
 
7
7
  * **Vue 3 Composition API**: Built from the ground up using modern, reactive Vue.js practices.
8
- * **Bootstrap 5 Integration**: Directly utilizes Bootstrap 5 CSS for consistency, without additional styling overhead.
9
- * **Data-Driven Components**: Pass data arrays to components with props and customize rendering with scoped slots.
10
- * **Lightweight & Modular**: Import only what you need, keeping your bundle small.
8
+ * **Full Bootstrap 5 Integration**: Automatically manages Bootstrap's JavaScript lifecycle, including dynamic initialization, reactive configuration, and memory cleanup.
9
+ * **Data-Driven & Reactive**: Components are fully reactive with `v-model` support and automatic updates when props or data change.
10
+ * **Smart Form Intelligence**: Automated ID generation and accessibility linking via `VibeFormGroup` context.
11
+ * **Zero-Boilerplate**: Components handle their own IDs, Teleportation, and Bootstrap instances internally.
11
12
  * **TypeScript Support**: Fully typed components for a great developer experience.
12
- * **Accessibility First**: Components crafted with accessibility and usability in mind.
13
+ * **Accessibility First**: Automatic ARIA attribute management and focus trapping.
13
14
 
14
15
  ## Installation
15
16
 
16
17
  Install via npm:
17
18
 
18
19
  ```bash
19
- npm install @velkymx/vibeui
20
+ npm install @velkymx/vibeui bootstrap
20
21
  ```
21
22
 
22
- Make sure you also install Bootstrap:
23
+ Optionally, install Bootstrap Icons or Quill for enhanced features:
23
24
 
24
25
  ```bash
25
- npm install bootstrap
26
- ```
27
-
28
- Optionally, install Bootstrap Icons for icon support:
29
-
30
- ```bash
31
- npm install bootstrap-icons
26
+ npm install bootstrap-icons quill
32
27
  ```
33
28
 
34
29
  ## Quick Setup
@@ -40,762 +35,57 @@ import { createApp } from 'vue';
40
35
  import App from './App.vue';
41
36
  import VibeUI from '@velkymx/vibeui';
42
37
  import 'bootstrap/dist/css/bootstrap.min.css';
43
- import 'bootstrap-icons/font/bootstrap-icons.css'; // Optional: for icon support
44
38
 
45
39
  createApp(App).use(VibeUI).mount('#app');
46
40
  ```
47
41
 
48
- ## Basic Usage
49
-
50
- Here's a quick example of the `VibeAlert` component:
51
-
52
- ```vue
53
- <script setup lang="ts">
54
- import { ref } from 'vue';
55
-
56
- const showAlert = ref(true);
57
- </script>
58
-
59
- <template>
60
- <VibeAlert variant="success" dismissable v-model="showAlert">
61
- Welcome to VibeUI!
62
- </VibeAlert>
63
- </template>
64
- ```
65
-
66
- ## Data-Driven Components
67
-
68
- VibeUI components are designed to be data-driven for maximum flexibility and maintainability:
69
-
70
- ### Basic Usage with Props
71
-
72
- Pass data arrays to components and let them handle the rendering:
73
-
74
- ```vue
75
- <template>
76
- <VibeBreadcrumb :items="breadcrumbItems" />
77
- <VibeNav tabs :items="navItems" />
78
- <VibeDropdown id="menu" text="Menu" :items="dropdownItems" />
79
- <VibePagination :total-pages="10" v-model:current-page="page" />
80
- </template>
81
-
82
- <script setup>
83
- import { ref } from 'vue'
84
-
85
- const page = ref(1)
86
-
87
- const breadcrumbItems = [
88
- { text: 'Home', href: '/' },
89
- { text: 'Products', href: '/products' },
90
- { text: 'Details', active: true }
91
- ]
92
-
93
- const navItems = [
94
- { text: 'Home', href: '#', active: true },
95
- { text: 'Features', href: '#' },
96
- { text: 'Pricing', href: '#' }
97
- ]
98
-
99
- const dropdownItems = [
100
- { text: 'Action', href: '#' },
101
- { text: 'Another action', href: '#' },
102
- { divider: true },
103
- { text: 'Separated link', href: '#' }
104
- ]
105
- </script>
106
- ```
107
-
108
- ### Custom Rendering with Scoped Slots
109
-
110
- Need to customize how items are rendered? Use scoped slots:
111
-
112
- ```vue
113
- <template>
114
- <!-- Custom item rendering -->
115
- <VibeBreadcrumb :items="breadcrumbItems">
116
- <template #item="{ item, index }">
117
- <VibeIcon :icon="item.icon" /> {{ item.text }}
118
- </template>
119
- </VibeBreadcrumb>
120
-
121
- <!-- Custom nav items with badges -->
122
- <VibeNav tabs :items="navItems">
123
- <template #item="{ item }">
124
- {{ item.text }}
125
- <VibeBadge v-if="item.count" variant="danger">{{ item.count }}</VibeBadge>
126
- </template>
127
- </VibeNav>
128
-
129
- <!-- Custom dropdown items -->
130
- <VibeDropdown id="menu" text="Menu" :items="dropdownItems">
131
- <template #item="{ item }">
132
- <VibeIcon :icon="item.icon" class="me-2" />
133
- {{ item.text }}
134
- </template>
135
- </VibeDropdown>
136
- </template>
137
-
138
- <script setup>
139
- const breadcrumbItems = [
140
- { text: 'Home', href: '/', icon: 'house-fill' },
141
- { text: 'Products', href: '/products', icon: 'box' },
142
- { text: 'Details', active: true, icon: 'info-circle' }
143
- ]
144
-
145
- const navItems = [
146
- { text: 'Home', href: '#', active: true },
147
- { text: 'Messages', href: '#', count: 5 },
148
- { text: 'Settings', href: '#' }
149
- ]
150
-
151
- const dropdownItems = [
152
- { text: 'Profile', href: '#', icon: 'person' },
153
- { text: 'Settings', href: '#', icon: 'gear' },
154
- { divider: true },
155
- { text: 'Logout', href: '#', icon: 'box-arrow-right' }
156
- ]
157
- </script>
158
- ```
159
-
160
- Data-driven components include: `VibeBreadcrumb`, `VibeNav`, `VibeNavbarNav`, `VibePagination`, `VibeListGroup`, `VibeAccordion`, `VibeDropdown`, `VibeCarousel`, `VibeProgress`, and `VibeTabContent`.
161
-
162
- ## Tabs
163
-
164
- VibeUI provides complete tab functionality using a data-driven approach:
165
-
166
- ```vue
167
- <template>
168
- <VibeTabContent :panes="tabPanes">
169
- <template #pane="{ pane }">
170
- <h3>{{ pane.title }}</h3>
171
- <p>{{ pane.content }}</p>
172
- </template>
173
- </VibeTabContent>
174
- </template>
175
-
176
- <script setup>
177
- const tabPanes = [
178
- {
179
- id: 'home-tab',
180
- title: 'Home',
181
- content: 'This is the home tab content.',
182
- active: true
183
- },
184
- {
185
- id: 'profile-tab',
186
- title: 'Profile',
187
- content: 'This is the profile tab content.'
188
- },
189
- {
190
- id: 'contact-tab',
191
- title: 'Contact',
192
- content: 'This is the contact tab content.'
193
- }
194
- ]
195
- </script>
196
- ```
197
-
198
- **Key Features:**
199
- - Data-driven with `panes` array prop
200
- - Automatic Bootstrap tab behavior with proper ARIA attributes
201
- - Fade transitions enabled by default
202
- - Scoped slot for custom pane content
203
- - Works seamlessly with Bootstrap's JavaScript
204
-
205
- ## Bootstrap Icons
206
-
207
- VibeUI provides a convenient `VibeIcon` component for using [Bootstrap Icons](https://icons.getbootstrap.com/) (2000+ icons):
208
-
209
- ### Installation
210
-
211
- ```bash
212
- npm install bootstrap-icons
213
- ```
214
-
215
- Import the icon font CSS in your `main.ts`:
216
-
217
- ```typescript
218
- import 'bootstrap-icons/font/bootstrap-icons.css';
219
- ```
220
-
221
- ### Basic Usage
222
-
223
- ```vue
224
- <template>
225
- <!-- Simple icon -->
226
- <VibeIcon icon="heart-fill" />
227
-
228
- <!-- With color -->
229
- <VibeIcon icon="star-fill" color="gold" />
230
-
231
- <!-- With size -->
232
- <VibeIcon icon="house" size="2x" />
233
-
234
- <!-- Custom font size -->
235
- <VibeIcon icon="alarm" fontSize="2rem" />
236
-
237
- <!-- In a button -->
238
- <VibeButton variant="primary">
239
- <VibeIcon icon="download" /> Download
240
- </VibeButton>
241
- </template>
242
- ```
243
-
244
- ### Props
245
-
246
- - **icon** (required): Icon name from [Bootstrap Icons](https://icons.getbootstrap.com/)
247
- - **size**: Preset sizes: `'sm' | 'lg' | '1x' | '2x' | '3x' | '4x' | '5x'`
248
- - **fontSize**: Custom font size (e.g., `'1.5rem'`, `'24px'`)
249
- - **color**: Icon color (any CSS color value)
250
- - **customClass**: Additional CSS classes
251
- - **flipH**: Flip horizontally
252
- - **flipV**: Flip vertically
253
- - **rotate**: Rotate by degrees (`90`, `180`, or `270`)
254
-
255
- ### Advanced Examples
256
-
257
- ```vue
258
- <template>
259
- <!-- Flipped icon -->
260
- <VibeIcon icon="arrow-right" flipH />
261
-
262
- <!-- Rotated icon -->
263
- <VibeIcon icon="arrow-up" :rotate="90" />
264
-
265
- <!-- Large colored icon -->
266
- <VibeIcon icon="emoji-smile" size="5x" color="#0d6efd" />
267
-
268
- <!-- Icon with click handler -->
269
- <VibeIcon icon="trash" color="red" @click="deleteItem" style="cursor: pointer" />
270
-
271
- <!-- Icon in navigation -->
272
- <VibeNav :items="navItems">
273
- <template #item="{ item }">
274
- <VibeIcon :icon="item.icon" /> {{ item.text }}
275
- </template>
276
- </VibeNav>
277
- </template>
278
- ```
279
-
280
- **Browse all 2000+ icons at:** [https://icons.getbootstrap.com/](https://icons.getbootstrap.com/)
281
-
282
- ## Bootstrap Utilities
283
-
284
- Since VibeUI uses Bootstrap 5.3 CSS, **all Bootstrap utility classes are available** for use with any component or element. This includes spacing, colors, typography, borders, shadows, flexbox, positioning, and more.
285
-
286
- ### Common Utilities
287
-
288
- #### Spacing (Margin & Padding)
289
-
290
- ```vue
291
- <template>
292
- <!-- Margin utilities -->
293
- <VibeButton class="m-3">Margin all sides</VibeButton>
294
- <VibeButton class="mt-4 mb-2">Margin top & bottom</VibeButton>
295
- <VibeButton class="mx-auto">Centered with auto margin</VibeButton>
296
-
297
- <!-- Padding utilities -->
298
- <VibeCard class="p-4">Card with padding</VibeCard>
299
- <VibeCard class="px-5 py-3">Custom x/y padding</VibeCard>
300
- </template>
301
- ```
302
-
303
- #### Borders & Rounded Corners
304
-
305
- ```vue
306
- <template>
307
- <!-- Border utilities -->
308
- <VibeCard class="border border-primary">Primary border</VibeCard>
309
- <VibeCard class="border-top border-3">Thick top border</VibeCard>
310
- <VibeCard class="border-0">No border</VibeCard>
311
-
312
- <!-- Rounded corners -->
313
- <VibeButton class="rounded-pill">Pill shaped</VibeButton>
314
- <VibeCard class="rounded-0">Sharp corners</VibeCard>
315
- <VibeCard class="rounded-3">More rounded</VibeCard>
316
- </template>
317
- ```
318
-
319
- #### Shadows
320
-
321
- ```vue
322
- <template>
323
- <VibeCard class="shadow-sm">Small shadow</VibeCard>
324
- <VibeCard class="shadow">Regular shadow</VibeCard>
325
- <VibeCard class="shadow-lg">Large shadow</VibeCard>
326
- </template>
327
- ```
328
-
329
- #### Colors (Text & Background)
330
-
331
- ```vue
332
- <template>
333
- <!-- Text colors -->
334
- <VibeAlert class="text-primary">Primary text</VibeAlert>
335
- <VibeAlert class="text-success">Success text</VibeAlert>
336
- <VibeAlert class="text-danger">Danger text</VibeAlert>
337
-
338
- <!-- Background colors -->
339
- <div class="bg-light p-3">Light background</div>
340
- <div class="bg-primary text-white p-3">Primary background</div>
341
-
342
- <!-- Background opacity -->
343
- <div class="bg-success bg-opacity-25 p-3">25% opacity</div>
344
- </template>
345
- ```
346
-
347
- #### Opacity
42
+ ## Advanced Interactivity
348
43
 
349
- ```vue
350
- <template>
351
- <VibeIcon icon="star" class="opacity-25" />
352
- <VibeIcon icon="star" class="opacity-50" />
353
- <VibeIcon icon="star" class="opacity-75" />
354
- <VibeIcon icon="star" class="opacity-100" />
355
- </template>
356
- ```
357
-
358
- #### Flexbox
44
+ VibeUI v0.6.0+ fully abstracts Bootstrap's JavaScript. You no longer need to manually initialize tooltips, modals, or collapses.
359
45
 
360
46
  ```vue
361
47
  <template>
362
- <!-- Flex container -->
363
- <VibeCard class="d-flex justify-content-between align-items-center p-3">
364
- <span>Left content</span>
365
- <VibeButton>Right button</VibeButton>
366
- </VibeCard>
367
-
368
- <!-- Flex direction -->
369
- <div class="d-flex flex-column gap-3">
370
- <VibeButton>Button 1</VibeButton>
371
- <VibeButton>Button 2</VibeButton>
372
- </div>
48
+ <div>
49
+ <!-- Automatic tooltip initialization -->
50
+ <VibeTooltip text="I just work!">
51
+ <VibeButton>Hover Me</VibeButton>
52
+ </VibeTooltip>
373
53
 
374
- <!-- Flex responsive -->
375
- <div class="d-flex flex-column flex-md-row">
376
- <VibeCard>Card 1</VibeCard>
377
- <VibeCard>Card 2</VibeCard>
54
+ <!-- Full v-model support for Modals -->
55
+ <VibeModal v-model="showModal" title="Hello!">
56
+ Fully reactive and automated.
57
+ </VibeModal>
378
58
  </div>
379
59
  </template>
380
60
  ```
381
61
 
382
- #### Position
383
-
384
- ```vue
385
- <template>
386
- <!-- Position utilities -->
387
- <div class="position-relative">
388
- <VibeIcon icon="bell" class="position-absolute top-0 end-0" />
389
- </div>
390
-
391
- <!-- Sticky positioning -->
392
- <VibeNavbar class="sticky-top">
393
- <!-- Navbar content -->
394
- </VibeNavbar>
395
-
396
- <!-- Fixed positioning -->
397
- <VibeButton class="position-fixed bottom-0 end-0 m-3">
398
- <VibeIcon icon="chat" />
399
- </VibeButton>
400
- </template>
401
- ```
402
-
403
- #### Display & Visibility
404
-
405
- ```vue
406
- <template>
407
- <!-- Display utilities -->
408
- <VibeAlert class="d-none d-md-block">Hidden on mobile</VibeAlert>
409
- <VibeButton class="d-inline-block">Inline block</VibeButton>
410
-
411
- <!-- Visibility -->
412
- <VibeCard class="visible">Visible</VibeCard>
413
- <VibeCard class="invisible">Invisible (takes space)</VibeCard>
414
- </template>
415
- ```
416
-
417
- #### Sizing
418
-
419
- ```vue
420
- <template>
421
- <!-- Width utilities -->
422
- <VibeButton class="w-100">Full width</VibeButton>
423
- <VibeButton class="w-75">75% width</VibeButton>
424
- <VibeButton class="w-auto">Auto width</VibeButton>
425
-
426
- <!-- Height utilities -->
427
- <div class="h-100">Full height</div>
428
- <div class="mh-100">Max height 100%</div>
429
-
430
- <!-- Viewport units -->
431
- <div class="vw-100">100% viewport width</div>
432
- <div class="vh-100">100% viewport height</div>
433
- </template>
434
- ```
435
-
436
- #### Typography
437
-
438
- ```vue
439
- <template>
440
- <!-- Font size -->
441
- <p class="fs-1">Very large text</p>
442
- <p class="fs-6">Small text</p>
443
-
444
- <!-- Font weight -->
445
- <span class="fw-bold">Bold</span>
446
- <span class="fw-light">Light</span>
447
-
448
- <!-- Text alignment -->
449
- <p class="text-start">Left aligned</p>
450
- <p class="text-center">Center aligned</p>
451
- <p class="text-end">Right aligned</p>
452
-
453
- <!-- Text transform -->
454
- <p class="text-uppercase">Uppercase</p>
455
- <p class="text-lowercase">Lowercase</p>
456
- <p class="text-capitalize">Capitalized</p>
457
- </template>
458
- ```
459
-
460
- ### Combined Examples
461
-
462
- ```vue
463
- <template>
464
- <!-- Card with multiple utilities -->
465
- <VibeCard class="shadow-lg rounded-3 border-0 p-4 mb-4">
466
- <div class="d-flex justify-content-between align-items-center mb-3">
467
- <h3 class="fw-bold text-primary mb-0">Card Title</h3>
468
- <VibeIcon icon="star-fill" class="text-warning" size="2x" />
469
- </div>
470
- <p class="text-muted mb-3">Card content with utilities</p>
471
- <VibeButton variant="primary" class="w-100">Full Width Button</VibeButton>
472
- </VibeCard>
473
-
474
- <!-- Responsive layout with utilities -->
475
- <VibeContainer>
476
- <VibeRow class="g-4">
477
- <VibeCol :cols="12" :md="6" :lg="4">
478
- <VibeCard class="h-100 shadow-sm hover-shadow">
479
- <div class="position-relative">
480
- <img src="..." class="w-100 rounded-top" />
481
- <VibeBadge class="position-absolute top-0 end-0 m-2">New</VibeBadge>
482
- </div>
483
- <div class="p-3">
484
- <h5 class="fw-semibold">Product Title</h5>
485
- <p class="text-muted small mb-3">Description</p>
486
- <div class="d-flex justify-content-between align-items-center">
487
- <span class="fs-4 fw-bold text-primary">$29.99</span>
488
- <VibeButton size="sm">
489
- <VibeIcon icon="cart-plus" /> Add
490
- </VibeButton>
491
- </div>
492
- </div>
493
- </VibeCard>
494
- </VibeCol>
495
- </VibeRow>
496
- </VibeContainer>
497
- </template>
498
- ```
499
-
500
- ### Full Documentation
501
-
502
- For complete details on all available utilities, see:
503
- - **[Bootstrap Utilities Documentation](https://getbootstrap.com/docs/5.3/utilities/api/)**
504
- - **[Spacing](https://getbootstrap.com/docs/5.3/utilities/spacing/)**
505
- - **[Colors](https://getbootstrap.com/docs/5.3/utilities/colors/)**
506
- - **[Borders](https://getbootstrap.com/docs/5.3/utilities/borders/)**
507
- - **[Shadows](https://getbootstrap.com/docs/5.3/utilities/shadows/)**
508
- - **[Flex](https://getbootstrap.com/docs/5.3/utilities/flex/)**
509
- - **[Position](https://getbootstrap.com/docs/5.3/utilities/position/)**
510
-
511
- ## Form Components with Validation
512
-
513
- VibeUI provides comprehensive form components with built-in validation support for both front-end and API-based validation:
62
+ ## Smart Forms
514
63
 
515
- ### Basic Form Example
64
+ VibeUI handles accessibility and IDs for you.
516
65
 
517
66
  ```vue
518
- <script setup lang="ts">
519
- import { ref } from 'vue'
520
- import { validators } from '@velkymx/vibeui'
521
-
522
- const email = ref('')
523
- const emailValidationState = ref(null)
524
- const emailValidationMessage = ref('')
525
-
526
- const validateEmail = async () => {
527
- const emailRules = [validators.required(), validators.email()]
528
-
529
- for (const rule of emailRules) {
530
- const result = await rule.validator(email.value)
531
- if (result !== true) {
532
- emailValidationState.value = 'invalid'
533
- emailValidationMessage.value = typeof result === 'string' ? result : rule.message
534
- return
535
- }
536
- }
537
-
538
- emailValidationState.value = 'valid'
539
- emailValidationMessage.value = ''
540
- }
541
- </script>
542
-
543
67
  <template>
544
- <VibeFormInput
545
- v-model="email"
546
- id="email"
547
- type="email"
548
- label="Email Address"
549
- placeholder="Enter your email"
550
- :validation-state="emailValidationState"
551
- :validation-message="emailValidationMessage"
552
- @validate="validateEmail"
553
- required
554
- />
68
+ <!-- No IDs required! Labels are automatically linked -->
69
+ <VibeFormGroup label="Email Address">
70
+ <VibeFormInput v-model="email" type="email" />
71
+ </VibeFormGroup>
555
72
  </template>
556
73
  ```
557
74
 
558
- ### Advanced Form with Composable
559
-
560
- ```vue
561
- <script setup lang="ts">
562
- import { ref } from 'vue'
563
- import { useFormValidation, validators } from '@velkymx/vibeui'
564
-
565
- const form = {
566
- username: useFormValidation(''),
567
- password: useFormValidation(''),
568
- age: useFormValidation(0),
569
- country: useFormValidation(''),
570
- agreeToTerms: useFormValidation(false)
571
- }
572
-
573
- const handleSubmit = async () => {
574
- const usernameValid = await form.username.validate([
575
- validators.required(),
576
- validators.minLength(3)
577
- ])
578
-
579
- const passwordValid = await form.password.validate([
580
- validators.required(),
581
- validators.minLength(8)
582
- ])
583
-
584
- const ageValid = await form.age.validate([
585
- validators.required(),
586
- validators.min(18)
587
- ])
588
-
589
- if (usernameValid.valid && passwordValid.valid && ageValid.valid) {
590
- console.log('Form is valid!')
591
- }
592
- }
593
- </script>
594
-
595
- <template>
596
- <form @submit.prevent="handleSubmit">
597
- <VibeFormInput
598
- v-model="form.username.value"
599
- id="username"
600
- label="Username"
601
- :validation-state="form.username.validationState"
602
- :validation-message="form.username.validationMessage"
603
- @validate="() => form.username.validate([validators.required(), validators.minLength(3)])"
604
- required
605
- />
606
-
607
- <VibeFormInput
608
- v-model="form.password.value"
609
- id="password"
610
- type="password"
611
- label="Password"
612
- :validation-state="form.password.validationState"
613
- :validation-message="form.password.validationMessage"
614
- @validate="() => form.password.validate([validators.required(), validators.minLength(8)])"
615
- required
616
- />
617
-
618
- <VibeFormSpinbutton
619
- v-model="form.age.value"
620
- id="age"
621
- label="Age"
622
- :min="0"
623
- :max="120"
624
- :validation-state="form.age.validationState"
625
- :validation-message="form.age.validationMessage"
626
- @validate="() => form.age.validate([validators.required(), validators.min(18)])"
627
- required
628
- />
629
-
630
- <VibeFormCheckbox
631
- v-model="form.agreeToTerms.value"
632
- id="terms"
633
- label="I agree to the terms and conditions"
634
- required
635
- />
636
-
637
- <VibeButton type="submit" variant="primary">Submit</VibeButton>
638
- </form>
639
- </template>
640
- ```
641
-
642
- ### API Validation Example
643
-
644
- ```vue
645
- <script setup lang="ts">
646
- import { ref } from 'vue'
647
- import { validators } from '@velkymx/vibeui'
648
-
649
- const username = ref('')
650
- const usernameValidationState = ref(null)
651
- const usernameValidationMessage = ref('')
652
-
653
- // Custom async validator for checking username availability
654
- const checkUsernameAvailability = validators.async(async (value) => {
655
- if (!value) return true
656
-
657
- try {
658
- const response = await fetch(`/api/check-username?username=${value}`)
659
- const data = await response.json()
660
-
661
- if (data.available) {
662
- return true
663
- } else {
664
- return 'Username is already taken'
665
- }
666
- } catch (error) {
667
- return 'Error checking username availability'
668
- }
669
- })
670
-
671
- const validateUsername = async () => {
672
- const rules = [
673
- validators.required(),
674
- validators.minLength(3),
675
- checkUsernameAvailability
676
- ]
677
-
678
- usernameValidationState.value = null
679
-
680
- for (const rule of rules) {
681
- const result = await rule.validator(username.value)
682
- if (result !== true) {
683
- usernameValidationState.value = 'invalid'
684
- usernameValidationMessage.value = typeof result === 'string' ? result : rule.message
685
- return
686
- }
687
- }
688
-
689
- usernameValidationState.value = 'valid'
690
- usernameValidationMessage.value = 'Username is available!'
691
- }
692
- </script>
693
-
694
- <template>
695
- <VibeFormInput
696
- v-model="username"
697
- id="username"
698
- label="Username"
699
- :validation-state="usernameValidationState"
700
- :validation-message="usernameValidationMessage"
701
- @validate="validateUsername"
702
- validate-on="blur"
703
- required
704
- />
705
- </template>
706
- ```
707
-
708
- ### Available Validators
709
-
710
- VibeUI provides built-in validators:
711
-
712
- - `validators.required(message?)` - Field is required
713
- - `validators.email(message?)` - Valid email format
714
- - `validators.minLength(min, message?)` - Minimum string length
715
- - `validators.maxLength(max, message?)` - Maximum string length
716
- - `validators.min(min, message?)` - Minimum numeric value
717
- - `validators.max(max, message?)` - Maximum numeric value
718
- - `validators.pattern(regex, message?)` - Custom regex pattern
719
- - `validators.url(message?)` - Valid URL format
720
- - `validators.async(asyncFn)` - Custom async validator
721
-
722
75
  ## Components
723
76
 
724
- VibeUI includes all major Bootstrap 5.3 components:
725
-
726
- ### Layout Components
727
- * **VibeContainer** - Responsive container with fluid and breakpoint variants
728
- * **VibeRow** - Row wrapper for columns with gutter control and row-cols support
729
- * **VibeCol** - Responsive grid columns with offset and order support
730
-
731
- ### Core Components
732
- * **VibeAlert** - Alert messages with variants and dismissible option
733
- * **VibeBadge** - Badges and labels with pill option
734
- * **VibeButton** - Buttons with variants, sizes, and outline style
735
- * **VibeButtonGroup** - Button groups with sizing and vertical layout
736
- * **VibeCloseButton** - Close button with white variant
737
- * **VibeSpinner** - Loading spinners (border and grow types)
738
- * **VibePlaceholder** - Placeholder loading states with animations
739
-
740
- ### Card Components
741
- * **VibeCard** - Card container with header, body, footer, and image support via props and named slots
742
-
743
- ### Navigation Components
744
- * **VibeBreadcrumb** - Data-driven breadcrumb navigation with `items` prop
745
- * **VibeNav** - Navigation tabs and pills with `items` prop
746
- * **VibeNavbar** - Responsive navbar with variants
747
- * **VibeNavbarBrand** - Navbar branding section
748
- * **VibeNavbarToggle** - Navbar mobile toggle button
749
- * **VibeNavbarNav** - Navbar navigation links with optional `items` prop
750
- * **VibePagination** - Data-driven pagination with `totalPages` prop and v-model support
751
- * **VibeTabContent** - Tab panes container with `panes` prop
752
-
753
- ### List Components
754
- * **VibeListGroup** - Data-driven list group with `items` prop, supports flush and horizontal layouts
755
-
756
- ### Progress Components
757
- * **VibeProgress** - Data-driven progress bars with `bars` prop, supports multiple bars with variants, striped, and animated styles
758
-
759
- ### Interactive Components
760
- * **VibeAccordion** - Data-driven accordion with `items` prop and flush option
761
- * **VibeCollapse** - Collapse component for showing/hiding content
762
- * **VibeDropdown** - Data-driven dropdown with `items` prop, supports variants, directions, dividers, and headers
763
- * **VibeModal** - Modal dialogs with sizes and positions
764
- * **VibeOffcanvas** - Offcanvas sidebars with placement options
765
- * **VibeToast** - Toast notifications with autohide
766
- * **VibeCarousel** - Data-driven image carousel with `items` prop, controls, and indicators
767
-
768
- ### Advanced Components
769
- * **VibeTooltip** - Tooltips with placement options (requires Bootstrap JS)
770
- * **VibePopover** - Popovers with title and content (requires Bootstrap JS)
771
- * **VibeScrollspy** - Scrollspy for navigation highlighting
772
- * **VibeIcon** - Bootstrap Icons integration with 2000+ icons
773
-
774
- ### Data Components
775
- * **VibeDataTable** - Powerful data table with search, sorting, and pagination
776
-
777
- ### Form Components
778
- * **VibeFormInput** - Text, email, password, number inputs with validation
779
- * **VibeFormSelect** - Select dropdowns with single/multiple selection
780
- * **VibeFormTextarea** - Multi-line text input with character count
781
- * **VibeFormSpinbutton** - Number input with increment/decrement buttons
782
- * **VibeFormDatepicker** - Date, time, and datetime input controls
783
- * **VibeFormCheckbox** - Checkboxes with support for arrays
784
- * **VibeFormRadio** - Radio button groups
785
- * **VibeFormSwitch** - Toggle switches
786
- * **VibeFormGroup** - Form group container with floating labels
787
- * **VibeFormWysiwyg** - WYSIWYG editor with QuillJS (requires quill package)
77
+ VibeUI includes all major Bootstrap 5.3 components, fully wrapped for Vue 3:
788
78
 
789
- All form components support:
790
- - Front-end validation with built-in validators
791
- - Async validation for API calls
792
- - Bootstrap 5 styling and validation states
793
- - Accessibility features
794
- - Custom validation messages
79
+ * **Layout**: Container, Row, Col
80
+ * **Core**: Alert, Badge, Button, ButtonGroup, CloseButton, Spinner, Placeholder, Icon
81
+ * **Navigation**: Breadcrumb, Nav, Navbar, Pagination, Scrollspy
82
+ * **Interactive**: Accordion, Collapse, Dropdown, Modal, Offcanvas, Toast, Carousel
83
+ * **Data**: DataTable
84
+ * **Forms**: Input, Select, Textarea, Spinbutton, Datepicker, Checkbox, Radio, Switch, Wysiwyg, FormGroup
795
85
 
796
- ## Contributing
86
+ ## Full Documentation
797
87
 
798
- Pull requests and contributions are very welcome! Please fork the repo, create a branch for your feature, and submit a PR.
88
+ For detailed documentation and examples, visit our [Docs](./docs/README.md).
799
89
 
800
90
  ## License
801
91