@velkymx/vibeui 0.2.0 → 0.4.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 +592 -1
- package/dist/App.vue.d.ts +2 -0
- package/dist/components/HelloWorld.vue.d.ts +5 -0
- package/dist/components/VibeAccordion.vue.d.ts +51 -0
- package/dist/components/VibeAccordionItem.vue.d.ts +57 -0
- package/dist/components/VibeAlert.vue.d.ts +61 -0
- package/dist/components/VibeBadge.vue.d.ts +52 -0
- package/dist/components/VibeBreadcrumb.vue.d.ts +43 -0
- package/dist/components/VibeBreadcrumbItem.vue.d.ts +51 -0
- package/dist/components/VibeButton.vue.d.ts +99 -0
- package/dist/components/VibeButtonGroup.vue.d.ts +61 -0
- package/dist/components/VibeCard.vue.d.ts +126 -0
- package/dist/components/VibeCardBody.vue.d.ts +34 -0
- package/dist/components/VibeCardFooter.vue.d.ts +34 -0
- package/dist/components/VibeCardHeader.vue.d.ts +34 -0
- package/dist/components/VibeCardImg.vue.d.ts +44 -0
- package/dist/components/VibeCardText.vue.d.ts +33 -0
- package/dist/components/VibeCardTitle.vue.d.ts +33 -0
- package/dist/components/VibeCarousel.vue.d.ts +137 -0
- package/dist/components/VibeCarouselSlide.vue.d.ts +80 -0
- package/dist/components/VibeCloseButton.vue.d.ts +38 -0
- package/dist/components/VibeCol.vue.d.ts +206 -0
- package/dist/components/VibeCollapse.vue.d.ts +70 -0
- package/dist/components/VibeContainer.vue.d.ts +44 -0
- package/dist/components/VibeDataTable.vue.d.ts +261 -0
- package/dist/components/VibeDropdown.vue.d.ts +96 -0
- package/dist/components/VibeDropdownItem.vue.d.ts +81 -0
- package/dist/components/VibeFormCheckbox.vue.d.ts +134 -0
- package/dist/components/VibeFormDatepicker.vue.d.ts +154 -0
- package/dist/components/VibeFormGroup.vue.d.ts +112 -0
- package/dist/components/VibeFormInput.vue.d.ts +154 -0
- package/dist/components/VibeFormRadio.vue.d.ts +132 -0
- package/dist/components/VibeFormSelect.vue.d.ts +167 -0
- package/dist/components/VibeFormSpinbutton.vue.d.ts +176 -0
- package/dist/components/VibeFormSwitch.vue.d.ts +107 -0
- package/dist/components/VibeFormTextarea.vue.d.ts +163 -0
- package/dist/components/VibeFormWysiwyg.vue.d.ts +156 -0
- package/dist/components/VibeIcon.vue.d.ts +83 -0
- package/dist/components/VibeListGroup.vue.d.ts +63 -0
- package/dist/components/VibeListGroupItem.vue.d.ts +90 -0
- package/dist/components/VibeModal.vue.d.ts +126 -0
- package/dist/components/VibeNav.vue.d.ts +81 -0
- package/dist/components/VibeNavItem.vue.d.ts +80 -0
- package/dist/components/VibeNavbar.vue.d.ts +71 -0
- package/dist/components/VibeNavbarBrand.vue.d.ts +42 -0
- package/dist/components/VibeNavbarNav.vue.d.ts +36 -0
- package/dist/components/VibeNavbarToggle.vue.d.ts +26 -0
- package/dist/components/VibeOffcanvas.vue.d.ts +89 -0
- package/dist/components/VibePagination.vue.d.ts +72 -0
- package/dist/components/VibePaginationItem.vue.d.ts +62 -0
- package/dist/components/VibePlaceholder.vue.d.ts +70 -0
- package/dist/components/VibePopover.vue.d.ts +69 -0
- package/dist/components/VibeProgress.vue.d.ts +33 -0
- package/dist/components/VibeProgressBar.vue.d.ts +88 -0
- package/dist/components/VibeRow.vue.d.ts +269 -0
- package/dist/components/VibeScrollspy.vue.d.ts +71 -0
- package/dist/components/VibeSpinner.vue.d.ts +55 -0
- package/dist/components/VibeTabContent.vue.d.ts +44 -0
- package/dist/components/VibeTabPane.vue.d.ts +70 -0
- package/dist/components/VibeToast.vue.d.ts +90 -0
- package/dist/components/VibeTooltip.vue.d.ts +60 -0
- package/dist/components/index.d.ts +63 -0
- package/dist/composables/useFormValidation.d.ts +26 -0
- package/dist/index.d.ts +3 -0
- package/dist/main.d.ts +0 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types.d.ts +100 -0
- package/dist/vibeui.css +1 -1
- package/dist/vibeui.es.js +1936 -704
- package/dist/vibeui.umd.js +1 -1
- package/package.json +14 -4
package/README.md
CHANGED
|
@@ -25,6 +25,12 @@ Make sure you also install Bootstrap:
|
|
|
25
25
|
npm install bootstrap
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
+
Optionally, install Bootstrap Icons for icon support:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install bootstrap-icons
|
|
32
|
+
```
|
|
33
|
+
|
|
28
34
|
## Quick Setup
|
|
29
35
|
|
|
30
36
|
In your Vue app's entry file (`main.ts` or `main.js`):
|
|
@@ -34,6 +40,7 @@ import { createApp } from 'vue';
|
|
|
34
40
|
import App from './App.vue';
|
|
35
41
|
import VibeUI from '@velkymx/vibeui';
|
|
36
42
|
import 'bootstrap/dist/css/bootstrap.min.css';
|
|
43
|
+
import 'bootstrap-icons/font/bootstrap-icons.css'; // Optional: for icon support
|
|
37
44
|
|
|
38
45
|
createApp(App).use(VibeUI).mount('#app');
|
|
39
46
|
```
|
|
@@ -122,10 +129,572 @@ For maximum flexibility and custom content:
|
|
|
122
129
|
|
|
123
130
|
Components with dual-mode support include: `VibeBreadcrumb`, `VibeNav`, `VibeNavbarNav`, `VibePagination`, `VibeListGroup`, `VibeAccordion`, `VibeDropdown`, and `VibeCarousel`.
|
|
124
131
|
|
|
132
|
+
## Tabs
|
|
133
|
+
|
|
134
|
+
VibeUI provides complete tab functionality following Bootstrap 5.3 patterns:
|
|
135
|
+
|
|
136
|
+
```vue
|
|
137
|
+
<template>
|
|
138
|
+
<!-- Tab Navigation -->
|
|
139
|
+
<VibeNav tabs>
|
|
140
|
+
<VibeNavItem tab active target="#home-tab">Home</VibeNavItem>
|
|
141
|
+
<VibeNavItem tab target="#profile-tab">Profile</VibeNavItem>
|
|
142
|
+
<VibeNavItem tab target="#contact-tab">Contact</VibeNavItem>
|
|
143
|
+
</VibeNav>
|
|
144
|
+
|
|
145
|
+
<!-- Tab Content -->
|
|
146
|
+
<VibeTabContent>
|
|
147
|
+
<VibeTabPane id="home-tab" active>
|
|
148
|
+
<h3>Home Content</h3>
|
|
149
|
+
<p>This is the home tab content.</p>
|
|
150
|
+
</VibeTabPane>
|
|
151
|
+
<VibeTabPane id="profile-tab">
|
|
152
|
+
<h3>Profile Content</h3>
|
|
153
|
+
<p>This is the profile tab content.</p>
|
|
154
|
+
</VibeTabPane>
|
|
155
|
+
<VibeTabPane id="contact-tab">
|
|
156
|
+
<h3>Contact Content</h3>
|
|
157
|
+
<p>This is the contact tab content.</p>
|
|
158
|
+
</VibeTabPane>
|
|
159
|
+
</VibeTabContent>
|
|
160
|
+
</template>
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
**Key Features:**
|
|
164
|
+
- Automatic Bootstrap tab behavior with proper `data-bs-toggle` and `data-bs-target` attributes
|
|
165
|
+
- Accessible with proper ARIA attributes
|
|
166
|
+
- Fade transitions enabled by default
|
|
167
|
+
- Works seamlessly with Bootstrap's JavaScript
|
|
168
|
+
|
|
169
|
+
## Bootstrap Icons
|
|
170
|
+
|
|
171
|
+
VibeUI provides a convenient `VibeIcon` component for using [Bootstrap Icons](https://icons.getbootstrap.com/) (2000+ icons):
|
|
172
|
+
|
|
173
|
+
### Installation
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
npm install bootstrap-icons
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Import the icon font CSS in your `main.ts`:
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
import 'bootstrap-icons/font/bootstrap-icons.css';
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Basic Usage
|
|
186
|
+
|
|
187
|
+
```vue
|
|
188
|
+
<template>
|
|
189
|
+
<!-- Simple icon -->
|
|
190
|
+
<VibeIcon icon="heart-fill" />
|
|
191
|
+
|
|
192
|
+
<!-- With color -->
|
|
193
|
+
<VibeIcon icon="star-fill" color="gold" />
|
|
194
|
+
|
|
195
|
+
<!-- With size -->
|
|
196
|
+
<VibeIcon icon="house" size="2x" />
|
|
197
|
+
|
|
198
|
+
<!-- Custom font size -->
|
|
199
|
+
<VibeIcon icon="alarm" fontSize="2rem" />
|
|
200
|
+
|
|
201
|
+
<!-- In a button -->
|
|
202
|
+
<VibeButton variant="primary">
|
|
203
|
+
<VibeIcon icon="download" /> Download
|
|
204
|
+
</VibeButton>
|
|
205
|
+
</template>
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Props
|
|
209
|
+
|
|
210
|
+
- **icon** (required): Icon name from [Bootstrap Icons](https://icons.getbootstrap.com/)
|
|
211
|
+
- **size**: Preset sizes: `'sm' | 'lg' | '1x' | '2x' | '3x' | '4x' | '5x'`
|
|
212
|
+
- **fontSize**: Custom font size (e.g., `'1.5rem'`, `'24px'`)
|
|
213
|
+
- **color**: Icon color (any CSS color value)
|
|
214
|
+
- **customClass**: Additional CSS classes
|
|
215
|
+
- **flipH**: Flip horizontally
|
|
216
|
+
- **flipV**: Flip vertically
|
|
217
|
+
- **rotate**: Rotate by degrees (`90`, `180`, or `270`)
|
|
218
|
+
|
|
219
|
+
### Advanced Examples
|
|
220
|
+
|
|
221
|
+
```vue
|
|
222
|
+
<template>
|
|
223
|
+
<!-- Flipped icon -->
|
|
224
|
+
<VibeIcon icon="arrow-right" flipH />
|
|
225
|
+
|
|
226
|
+
<!-- Rotated icon -->
|
|
227
|
+
<VibeIcon icon="arrow-up" :rotate="90" />
|
|
228
|
+
|
|
229
|
+
<!-- Large colored icon -->
|
|
230
|
+
<VibeIcon icon="emoji-smile" size="5x" color="#0d6efd" />
|
|
231
|
+
|
|
232
|
+
<!-- Icon with click handler -->
|
|
233
|
+
<VibeIcon icon="trash" color="red" @click="deleteItem" style="cursor: pointer" />
|
|
234
|
+
|
|
235
|
+
<!-- Icon in navigation -->
|
|
236
|
+
<VibeNav>
|
|
237
|
+
<VibeNavItem active>
|
|
238
|
+
<VibeIcon icon="house-fill" /> Home
|
|
239
|
+
</VibeNavItem>
|
|
240
|
+
<VibeNavItem>
|
|
241
|
+
<VibeIcon icon="person" /> Profile
|
|
242
|
+
</VibeNavItem>
|
|
243
|
+
</VibeNav>
|
|
244
|
+
</template>
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
**Browse all 2000+ icons at:** [https://icons.getbootstrap.com/](https://icons.getbootstrap.com/)
|
|
248
|
+
|
|
249
|
+
## Bootstrap Utilities
|
|
250
|
+
|
|
251
|
+
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.
|
|
252
|
+
|
|
253
|
+
### Common Utilities
|
|
254
|
+
|
|
255
|
+
#### Spacing (Margin & Padding)
|
|
256
|
+
|
|
257
|
+
```vue
|
|
258
|
+
<template>
|
|
259
|
+
<!-- Margin utilities -->
|
|
260
|
+
<VibeButton class="m-3">Margin all sides</VibeButton>
|
|
261
|
+
<VibeButton class="mt-4 mb-2">Margin top & bottom</VibeButton>
|
|
262
|
+
<VibeButton class="mx-auto">Centered with auto margin</VibeButton>
|
|
263
|
+
|
|
264
|
+
<!-- Padding utilities -->
|
|
265
|
+
<VibeCard class="p-4">Card with padding</VibeCard>
|
|
266
|
+
<VibeCard class="px-5 py-3">Custom x/y padding</VibeCard>
|
|
267
|
+
</template>
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
#### Borders & Rounded Corners
|
|
271
|
+
|
|
272
|
+
```vue
|
|
273
|
+
<template>
|
|
274
|
+
<!-- Border utilities -->
|
|
275
|
+
<VibeCard class="border border-primary">Primary border</VibeCard>
|
|
276
|
+
<VibeCard class="border-top border-3">Thick top border</VibeCard>
|
|
277
|
+
<VibeCard class="border-0">No border</VibeCard>
|
|
278
|
+
|
|
279
|
+
<!-- Rounded corners -->
|
|
280
|
+
<VibeButton class="rounded-pill">Pill shaped</VibeButton>
|
|
281
|
+
<VibeCard class="rounded-0">Sharp corners</VibeCard>
|
|
282
|
+
<VibeCard class="rounded-3">More rounded</VibeCard>
|
|
283
|
+
</template>
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
#### Shadows
|
|
287
|
+
|
|
288
|
+
```vue
|
|
289
|
+
<template>
|
|
290
|
+
<VibeCard class="shadow-sm">Small shadow</VibeCard>
|
|
291
|
+
<VibeCard class="shadow">Regular shadow</VibeCard>
|
|
292
|
+
<VibeCard class="shadow-lg">Large shadow</VibeCard>
|
|
293
|
+
</template>
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
#### Colors (Text & Background)
|
|
297
|
+
|
|
298
|
+
```vue
|
|
299
|
+
<template>
|
|
300
|
+
<!-- Text colors -->
|
|
301
|
+
<VibeAlert class="text-primary">Primary text</VibeAlert>
|
|
302
|
+
<VibeAlert class="text-success">Success text</VibeAlert>
|
|
303
|
+
<VibeAlert class="text-danger">Danger text</VibeAlert>
|
|
304
|
+
|
|
305
|
+
<!-- Background colors -->
|
|
306
|
+
<div class="bg-light p-3">Light background</div>
|
|
307
|
+
<div class="bg-primary text-white p-3">Primary background</div>
|
|
308
|
+
|
|
309
|
+
<!-- Background opacity -->
|
|
310
|
+
<div class="bg-success bg-opacity-25 p-3">25% opacity</div>
|
|
311
|
+
</template>
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
#### Opacity
|
|
315
|
+
|
|
316
|
+
```vue
|
|
317
|
+
<template>
|
|
318
|
+
<VibeIcon icon="star" class="opacity-25" />
|
|
319
|
+
<VibeIcon icon="star" class="opacity-50" />
|
|
320
|
+
<VibeIcon icon="star" class="opacity-75" />
|
|
321
|
+
<VibeIcon icon="star" class="opacity-100" />
|
|
322
|
+
</template>
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
#### Flexbox
|
|
326
|
+
|
|
327
|
+
```vue
|
|
328
|
+
<template>
|
|
329
|
+
<!-- Flex container -->
|
|
330
|
+
<VibeCard class="d-flex justify-content-between align-items-center p-3">
|
|
331
|
+
<span>Left content</span>
|
|
332
|
+
<VibeButton>Right button</VibeButton>
|
|
333
|
+
</VibeCard>
|
|
334
|
+
|
|
335
|
+
<!-- Flex direction -->
|
|
336
|
+
<div class="d-flex flex-column gap-3">
|
|
337
|
+
<VibeButton>Button 1</VibeButton>
|
|
338
|
+
<VibeButton>Button 2</VibeButton>
|
|
339
|
+
</div>
|
|
340
|
+
|
|
341
|
+
<!-- Flex responsive -->
|
|
342
|
+
<div class="d-flex flex-column flex-md-row">
|
|
343
|
+
<VibeCard>Card 1</VibeCard>
|
|
344
|
+
<VibeCard>Card 2</VibeCard>
|
|
345
|
+
</div>
|
|
346
|
+
</template>
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
#### Position
|
|
350
|
+
|
|
351
|
+
```vue
|
|
352
|
+
<template>
|
|
353
|
+
<!-- Position utilities -->
|
|
354
|
+
<div class="position-relative">
|
|
355
|
+
<VibeIcon icon="bell" class="position-absolute top-0 end-0" />
|
|
356
|
+
</div>
|
|
357
|
+
|
|
358
|
+
<!-- Sticky positioning -->
|
|
359
|
+
<VibeNavbar class="sticky-top">
|
|
360
|
+
<!-- Navbar content -->
|
|
361
|
+
</VibeNavbar>
|
|
362
|
+
|
|
363
|
+
<!-- Fixed positioning -->
|
|
364
|
+
<VibeButton class="position-fixed bottom-0 end-0 m-3">
|
|
365
|
+
<VibeIcon icon="chat" />
|
|
366
|
+
</VibeButton>
|
|
367
|
+
</template>
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
#### Display & Visibility
|
|
371
|
+
|
|
372
|
+
```vue
|
|
373
|
+
<template>
|
|
374
|
+
<!-- Display utilities -->
|
|
375
|
+
<VibeAlert class="d-none d-md-block">Hidden on mobile</VibeAlert>
|
|
376
|
+
<VibeButton class="d-inline-block">Inline block</VibeButton>
|
|
377
|
+
|
|
378
|
+
<!-- Visibility -->
|
|
379
|
+
<VibeCard class="visible">Visible</VibeCard>
|
|
380
|
+
<VibeCard class="invisible">Invisible (takes space)</VibeCard>
|
|
381
|
+
</template>
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
#### Sizing
|
|
385
|
+
|
|
386
|
+
```vue
|
|
387
|
+
<template>
|
|
388
|
+
<!-- Width utilities -->
|
|
389
|
+
<VibeButton class="w-100">Full width</VibeButton>
|
|
390
|
+
<VibeButton class="w-75">75% width</VibeButton>
|
|
391
|
+
<VibeButton class="w-auto">Auto width</VibeButton>
|
|
392
|
+
|
|
393
|
+
<!-- Height utilities -->
|
|
394
|
+
<div class="h-100">Full height</div>
|
|
395
|
+
<div class="mh-100">Max height 100%</div>
|
|
396
|
+
|
|
397
|
+
<!-- Viewport units -->
|
|
398
|
+
<div class="vw-100">100% viewport width</div>
|
|
399
|
+
<div class="vh-100">100% viewport height</div>
|
|
400
|
+
</template>
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
#### Typography
|
|
404
|
+
|
|
405
|
+
```vue
|
|
406
|
+
<template>
|
|
407
|
+
<!-- Font size -->
|
|
408
|
+
<p class="fs-1">Very large text</p>
|
|
409
|
+
<p class="fs-6">Small text</p>
|
|
410
|
+
|
|
411
|
+
<!-- Font weight -->
|
|
412
|
+
<span class="fw-bold">Bold</span>
|
|
413
|
+
<span class="fw-light">Light</span>
|
|
414
|
+
|
|
415
|
+
<!-- Text alignment -->
|
|
416
|
+
<p class="text-start">Left aligned</p>
|
|
417
|
+
<p class="text-center">Center aligned</p>
|
|
418
|
+
<p class="text-end">Right aligned</p>
|
|
419
|
+
|
|
420
|
+
<!-- Text transform -->
|
|
421
|
+
<p class="text-uppercase">Uppercase</p>
|
|
422
|
+
<p class="text-lowercase">Lowercase</p>
|
|
423
|
+
<p class="text-capitalize">Capitalized</p>
|
|
424
|
+
</template>
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
### Combined Examples
|
|
428
|
+
|
|
429
|
+
```vue
|
|
430
|
+
<template>
|
|
431
|
+
<!-- Card with multiple utilities -->
|
|
432
|
+
<VibeCard class="shadow-lg rounded-3 border-0 p-4 mb-4">
|
|
433
|
+
<div class="d-flex justify-content-between align-items-center mb-3">
|
|
434
|
+
<h3 class="fw-bold text-primary mb-0">Card Title</h3>
|
|
435
|
+
<VibeIcon icon="star-fill" class="text-warning" size="2x" />
|
|
436
|
+
</div>
|
|
437
|
+
<p class="text-muted mb-3">Card content with utilities</p>
|
|
438
|
+
<VibeButton variant="primary" class="w-100">Full Width Button</VibeButton>
|
|
439
|
+
</VibeCard>
|
|
440
|
+
|
|
441
|
+
<!-- Responsive layout with utilities -->
|
|
442
|
+
<VibeContainer>
|
|
443
|
+
<VibeRow class="g-4">
|
|
444
|
+
<VibeCol :cols="12" :md="6" :lg="4">
|
|
445
|
+
<VibeCard class="h-100 shadow-sm hover-shadow">
|
|
446
|
+
<div class="position-relative">
|
|
447
|
+
<img src="..." class="w-100 rounded-top" />
|
|
448
|
+
<VibeBadge class="position-absolute top-0 end-0 m-2">New</VibeBadge>
|
|
449
|
+
</div>
|
|
450
|
+
<div class="p-3">
|
|
451
|
+
<h5 class="fw-semibold">Product Title</h5>
|
|
452
|
+
<p class="text-muted small mb-3">Description</p>
|
|
453
|
+
<div class="d-flex justify-content-between align-items-center">
|
|
454
|
+
<span class="fs-4 fw-bold text-primary">$29.99</span>
|
|
455
|
+
<VibeButton size="sm">
|
|
456
|
+
<VibeIcon icon="cart-plus" /> Add
|
|
457
|
+
</VibeButton>
|
|
458
|
+
</div>
|
|
459
|
+
</div>
|
|
460
|
+
</VibeCard>
|
|
461
|
+
</VibeCol>
|
|
462
|
+
</VibeRow>
|
|
463
|
+
</VibeContainer>
|
|
464
|
+
</template>
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
### Full Documentation
|
|
468
|
+
|
|
469
|
+
For complete details on all available utilities, see:
|
|
470
|
+
- **[Bootstrap Utilities Documentation](https://getbootstrap.com/docs/5.3/utilities/api/)**
|
|
471
|
+
- **[Spacing](https://getbootstrap.com/docs/5.3/utilities/spacing/)**
|
|
472
|
+
- **[Colors](https://getbootstrap.com/docs/5.3/utilities/colors/)**
|
|
473
|
+
- **[Borders](https://getbootstrap.com/docs/5.3/utilities/borders/)**
|
|
474
|
+
- **[Shadows](https://getbootstrap.com/docs/5.3/utilities/shadows/)**
|
|
475
|
+
- **[Flex](https://getbootstrap.com/docs/5.3/utilities/flex/)**
|
|
476
|
+
- **[Position](https://getbootstrap.com/docs/5.3/utilities/position/)**
|
|
477
|
+
|
|
478
|
+
## Form Components with Validation
|
|
479
|
+
|
|
480
|
+
VibeUI provides comprehensive form components with built-in validation support for both front-end and API-based validation:
|
|
481
|
+
|
|
482
|
+
### Basic Form Example
|
|
483
|
+
|
|
484
|
+
```vue
|
|
485
|
+
<script setup lang="ts">
|
|
486
|
+
import { ref } from 'vue'
|
|
487
|
+
import { validators } from '@velkymx/vibeui'
|
|
488
|
+
|
|
489
|
+
const email = ref('')
|
|
490
|
+
const emailValidationState = ref(null)
|
|
491
|
+
const emailValidationMessage = ref('')
|
|
492
|
+
|
|
493
|
+
const validateEmail = async () => {
|
|
494
|
+
const emailRules = [validators.required(), validators.email()]
|
|
495
|
+
|
|
496
|
+
for (const rule of emailRules) {
|
|
497
|
+
const result = await rule.validator(email.value)
|
|
498
|
+
if (result !== true) {
|
|
499
|
+
emailValidationState.value = 'invalid'
|
|
500
|
+
emailValidationMessage.value = typeof result === 'string' ? result : rule.message
|
|
501
|
+
return
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
emailValidationState.value = 'valid'
|
|
506
|
+
emailValidationMessage.value = ''
|
|
507
|
+
}
|
|
508
|
+
</script>
|
|
509
|
+
|
|
510
|
+
<template>
|
|
511
|
+
<VibeFormInput
|
|
512
|
+
v-model="email"
|
|
513
|
+
id="email"
|
|
514
|
+
type="email"
|
|
515
|
+
label="Email Address"
|
|
516
|
+
placeholder="Enter your email"
|
|
517
|
+
:validation-state="emailValidationState"
|
|
518
|
+
:validation-message="emailValidationMessage"
|
|
519
|
+
@validate="validateEmail"
|
|
520
|
+
required
|
|
521
|
+
/>
|
|
522
|
+
</template>
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
### Advanced Form with Composable
|
|
526
|
+
|
|
527
|
+
```vue
|
|
528
|
+
<script setup lang="ts">
|
|
529
|
+
import { ref } from 'vue'
|
|
530
|
+
import { useFormValidation, validators } from '@velkymx/vibeui'
|
|
531
|
+
|
|
532
|
+
const form = {
|
|
533
|
+
username: useFormValidation(''),
|
|
534
|
+
password: useFormValidation(''),
|
|
535
|
+
age: useFormValidation(0),
|
|
536
|
+
country: useFormValidation(''),
|
|
537
|
+
agreeToTerms: useFormValidation(false)
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
const handleSubmit = async () => {
|
|
541
|
+
const usernameValid = await form.username.validate([
|
|
542
|
+
validators.required(),
|
|
543
|
+
validators.minLength(3)
|
|
544
|
+
])
|
|
545
|
+
|
|
546
|
+
const passwordValid = await form.password.validate([
|
|
547
|
+
validators.required(),
|
|
548
|
+
validators.minLength(8)
|
|
549
|
+
])
|
|
550
|
+
|
|
551
|
+
const ageValid = await form.age.validate([
|
|
552
|
+
validators.required(),
|
|
553
|
+
validators.min(18)
|
|
554
|
+
])
|
|
555
|
+
|
|
556
|
+
if (usernameValid.valid && passwordValid.valid && ageValid.valid) {
|
|
557
|
+
console.log('Form is valid!')
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
</script>
|
|
561
|
+
|
|
562
|
+
<template>
|
|
563
|
+
<form @submit.prevent="handleSubmit">
|
|
564
|
+
<VibeFormInput
|
|
565
|
+
v-model="form.username.value"
|
|
566
|
+
id="username"
|
|
567
|
+
label="Username"
|
|
568
|
+
:validation-state="form.username.validationState"
|
|
569
|
+
:validation-message="form.username.validationMessage"
|
|
570
|
+
@validate="() => form.username.validate([validators.required(), validators.minLength(3)])"
|
|
571
|
+
required
|
|
572
|
+
/>
|
|
573
|
+
|
|
574
|
+
<VibeFormInput
|
|
575
|
+
v-model="form.password.value"
|
|
576
|
+
id="password"
|
|
577
|
+
type="password"
|
|
578
|
+
label="Password"
|
|
579
|
+
:validation-state="form.password.validationState"
|
|
580
|
+
:validation-message="form.password.validationMessage"
|
|
581
|
+
@validate="() => form.password.validate([validators.required(), validators.minLength(8)])"
|
|
582
|
+
required
|
|
583
|
+
/>
|
|
584
|
+
|
|
585
|
+
<VibeFormSpinbutton
|
|
586
|
+
v-model="form.age.value"
|
|
587
|
+
id="age"
|
|
588
|
+
label="Age"
|
|
589
|
+
:min="0"
|
|
590
|
+
:max="120"
|
|
591
|
+
:validation-state="form.age.validationState"
|
|
592
|
+
:validation-message="form.age.validationMessage"
|
|
593
|
+
@validate="() => form.age.validate([validators.required(), validators.min(18)])"
|
|
594
|
+
required
|
|
595
|
+
/>
|
|
596
|
+
|
|
597
|
+
<VibeFormCheckbox
|
|
598
|
+
v-model="form.agreeToTerms.value"
|
|
599
|
+
id="terms"
|
|
600
|
+
label="I agree to the terms and conditions"
|
|
601
|
+
required
|
|
602
|
+
/>
|
|
603
|
+
|
|
604
|
+
<VibeButton type="submit" variant="primary">Submit</VibeButton>
|
|
605
|
+
</form>
|
|
606
|
+
</template>
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
### API Validation Example
|
|
610
|
+
|
|
611
|
+
```vue
|
|
612
|
+
<script setup lang="ts">
|
|
613
|
+
import { ref } from 'vue'
|
|
614
|
+
import { validators } from '@velkymx/vibeui'
|
|
615
|
+
|
|
616
|
+
const username = ref('')
|
|
617
|
+
const usernameValidationState = ref(null)
|
|
618
|
+
const usernameValidationMessage = ref('')
|
|
619
|
+
|
|
620
|
+
// Custom async validator for checking username availability
|
|
621
|
+
const checkUsernameAvailability = validators.async(async (value) => {
|
|
622
|
+
if (!value) return true
|
|
623
|
+
|
|
624
|
+
try {
|
|
625
|
+
const response = await fetch(`/api/check-username?username=${value}`)
|
|
626
|
+
const data = await response.json()
|
|
627
|
+
|
|
628
|
+
if (data.available) {
|
|
629
|
+
return true
|
|
630
|
+
} else {
|
|
631
|
+
return 'Username is already taken'
|
|
632
|
+
}
|
|
633
|
+
} catch (error) {
|
|
634
|
+
return 'Error checking username availability'
|
|
635
|
+
}
|
|
636
|
+
})
|
|
637
|
+
|
|
638
|
+
const validateUsername = async () => {
|
|
639
|
+
const rules = [
|
|
640
|
+
validators.required(),
|
|
641
|
+
validators.minLength(3),
|
|
642
|
+
checkUsernameAvailability
|
|
643
|
+
]
|
|
644
|
+
|
|
645
|
+
usernameValidationState.value = null
|
|
646
|
+
|
|
647
|
+
for (const rule of rules) {
|
|
648
|
+
const result = await rule.validator(username.value)
|
|
649
|
+
if (result !== true) {
|
|
650
|
+
usernameValidationState.value = 'invalid'
|
|
651
|
+
usernameValidationMessage.value = typeof result === 'string' ? result : rule.message
|
|
652
|
+
return
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
usernameValidationState.value = 'valid'
|
|
657
|
+
usernameValidationMessage.value = 'Username is available!'
|
|
658
|
+
}
|
|
659
|
+
</script>
|
|
660
|
+
|
|
661
|
+
<template>
|
|
662
|
+
<VibeFormInput
|
|
663
|
+
v-model="username"
|
|
664
|
+
id="username"
|
|
665
|
+
label="Username"
|
|
666
|
+
:validation-state="usernameValidationState"
|
|
667
|
+
:validation-message="usernameValidationMessage"
|
|
668
|
+
@validate="validateUsername"
|
|
669
|
+
validate-on="blur"
|
|
670
|
+
required
|
|
671
|
+
/>
|
|
672
|
+
</template>
|
|
673
|
+
```
|
|
674
|
+
|
|
675
|
+
### Available Validators
|
|
676
|
+
|
|
677
|
+
VibeUI provides built-in validators:
|
|
678
|
+
|
|
679
|
+
- `validators.required(message?)` - Field is required
|
|
680
|
+
- `validators.email(message?)` - Valid email format
|
|
681
|
+
- `validators.minLength(min, message?)` - Minimum string length
|
|
682
|
+
- `validators.maxLength(max, message?)` - Maximum string length
|
|
683
|
+
- `validators.min(min, message?)` - Minimum numeric value
|
|
684
|
+
- `validators.max(max, message?)` - Maximum numeric value
|
|
685
|
+
- `validators.pattern(regex, message?)` - Custom regex pattern
|
|
686
|
+
- `validators.url(message?)` - Valid URL format
|
|
687
|
+
- `validators.async(asyncFn)` - Custom async validator
|
|
688
|
+
|
|
125
689
|
## Components
|
|
126
690
|
|
|
127
691
|
VibeUI includes all major Bootstrap 5.3 components:
|
|
128
692
|
|
|
693
|
+
### Layout Components
|
|
694
|
+
* **VibeContainer** - Responsive container with fluid and breakpoint variants
|
|
695
|
+
* **VibeRow** - Row wrapper for columns with gutter control and row-cols support
|
|
696
|
+
* **VibeCol** - Responsive grid columns with offset and order support
|
|
697
|
+
|
|
129
698
|
### Core Components
|
|
130
699
|
* **VibeAlert** - Alert messages with variants and dismissible option
|
|
131
700
|
* **VibeBadge** - Badges and labels with pill option
|
|
@@ -148,13 +717,15 @@ VibeUI includes all major Bootstrap 5.3 components:
|
|
|
148
717
|
* **VibeBreadcrumb** - Breadcrumb navigation container
|
|
149
718
|
* **VibeBreadcrumbItem** - Individual breadcrumb items
|
|
150
719
|
* **VibeNav** - Navigation tabs and pills
|
|
151
|
-
* **VibeNavItem** - Navigation items with active state
|
|
720
|
+
* **VibeNavItem** - Navigation items with active state and tab support
|
|
152
721
|
* **VibeNavbar** - Responsive navbar with variants
|
|
153
722
|
* **VibeNavbarBrand** - Navbar branding section
|
|
154
723
|
* **VibeNavbarToggle** - Navbar mobile toggle button
|
|
155
724
|
* **VibeNavbarNav** - Navbar navigation links container
|
|
156
725
|
* **VibePagination** - Pagination container
|
|
157
726
|
* **VibePaginationItem** - Individual pagination items
|
|
727
|
+
* **VibeTabContent** - Container for tab panes
|
|
728
|
+
* **VibeTabPane** - Individual tab panel content
|
|
158
729
|
|
|
159
730
|
### List Components
|
|
160
731
|
* **VibeListGroup** - List group container with flush and horizontal options
|
|
@@ -180,10 +751,30 @@ VibeUI includes all major Bootstrap 5.3 components:
|
|
|
180
751
|
* **VibeTooltip** - Tooltips with placement options (requires Bootstrap JS)
|
|
181
752
|
* **VibePopover** - Popovers with title and content (requires Bootstrap JS)
|
|
182
753
|
* **VibeScrollspy** - Scrollspy for navigation highlighting
|
|
754
|
+
* **VibeIcon** - Bootstrap Icons integration with 2000+ icons
|
|
183
755
|
|
|
184
756
|
### Data Components
|
|
185
757
|
* **VibeDataTable** - Powerful data table with search, sorting, and pagination
|
|
186
758
|
|
|
759
|
+
### Form Components
|
|
760
|
+
* **VibeFormInput** - Text, email, password, number inputs with validation
|
|
761
|
+
* **VibeFormSelect** - Select dropdowns with single/multiple selection
|
|
762
|
+
* **VibeFormTextarea** - Multi-line text input with character count
|
|
763
|
+
* **VibeFormSpinbutton** - Number input with increment/decrement buttons
|
|
764
|
+
* **VibeFormDatepicker** - Date, time, and datetime input controls
|
|
765
|
+
* **VibeFormCheckbox** - Checkboxes with support for arrays
|
|
766
|
+
* **VibeFormRadio** - Radio button groups
|
|
767
|
+
* **VibeFormSwitch** - Toggle switches
|
|
768
|
+
* **VibeFormGroup** - Form group container with floating labels
|
|
769
|
+
* **VibeFormWysiwyg** - WYSIWYG editor with QuillJS (requires quill package)
|
|
770
|
+
|
|
771
|
+
All form components support:
|
|
772
|
+
- Front-end validation with built-in validators
|
|
773
|
+
- Async validation for API calls
|
|
774
|
+
- Bootstrap 5 styling and validation states
|
|
775
|
+
- Accessibility features
|
|
776
|
+
- Custom validation messages
|
|
777
|
+
|
|
187
778
|
## Contributing
|
|
188
779
|
|
|
189
780
|
Pull requests and contributions are very welcome! Please fork the repo, create a branch for your feature, and submit a PR.
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
declare const _default: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
export default _default;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
msg: string;
|
|
3
|
+
};
|
|
4
|
+
declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
5
|
+
export default _default;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { AccordionItem } from '../types';
|
|
2
|
+
declare function __VLS_template(): {
|
|
3
|
+
attrs: Partial<{}>;
|
|
4
|
+
slots: {
|
|
5
|
+
default?(_: {}): any;
|
|
6
|
+
};
|
|
7
|
+
refs: {};
|
|
8
|
+
rootEl: HTMLDivElement;
|
|
9
|
+
};
|
|
10
|
+
type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
|
|
11
|
+
declare const __VLS_component: import('vue').DefineComponent<import('vue').ExtractPropTypes<{
|
|
12
|
+
id: {
|
|
13
|
+
type: StringConstructor;
|
|
14
|
+
required: true;
|
|
15
|
+
};
|
|
16
|
+
flush: {
|
|
17
|
+
type: BooleanConstructor;
|
|
18
|
+
default: boolean;
|
|
19
|
+
};
|
|
20
|
+
items: {
|
|
21
|
+
type: () => AccordionItem[];
|
|
22
|
+
default: undefined;
|
|
23
|
+
};
|
|
24
|
+
}>, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
|
|
25
|
+
"component-error": (...args: any[]) => void;
|
|
26
|
+
}, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<{
|
|
27
|
+
id: {
|
|
28
|
+
type: StringConstructor;
|
|
29
|
+
required: true;
|
|
30
|
+
};
|
|
31
|
+
flush: {
|
|
32
|
+
type: BooleanConstructor;
|
|
33
|
+
default: boolean;
|
|
34
|
+
};
|
|
35
|
+
items: {
|
|
36
|
+
type: () => AccordionItem[];
|
|
37
|
+
default: undefined;
|
|
38
|
+
};
|
|
39
|
+
}>> & Readonly<{
|
|
40
|
+
"onComponent-error"?: ((...args: any[]) => any) | undefined;
|
|
41
|
+
}>, {
|
|
42
|
+
items: AccordionItem[];
|
|
43
|
+
flush: boolean;
|
|
44
|
+
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, HTMLDivElement>;
|
|
45
|
+
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
|
|
46
|
+
export default _default;
|
|
47
|
+
type __VLS_WithTemplateSlots<T, S> = T & {
|
|
48
|
+
new (): {
|
|
49
|
+
$slots: S;
|
|
50
|
+
};
|
|
51
|
+
};
|