@velkymx/vibeui 0.5.4 → 0.7.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 +34 -744
- package/dist/components/VibeAccordion.vue.d.ts +36 -5
- package/dist/components/VibeAlert.vue.d.ts +19 -2
- package/dist/components/VibeCarousel.vue.d.ts +47 -6
- package/dist/components/VibeCollapse.vue.d.ts +9 -4
- package/dist/components/VibeDropdown.vue.d.ts +32 -5
- package/dist/components/VibeFormCheckbox.vue.d.ts +30 -22
- package/dist/components/VibeFormDatepicker.vue.d.ts +3 -2
- package/dist/components/VibeFormInput.vue.d.ts +4 -3
- package/dist/components/VibeFormRadio.vue.d.ts +33 -25
- package/dist/components/VibeFormSelect.vue.d.ts +46 -38
- package/dist/components/VibeFormSpinbutton.vue.d.ts +9 -8
- package/dist/components/VibeFormSwitch.vue.d.ts +16 -8
- package/dist/components/VibeFormTextarea.vue.d.ts +36 -28
- package/dist/components/VibeFormWysiwyg.vue.d.ts +3 -2
- package/dist/components/VibeModal.vue.d.ts +36 -5
- package/dist/components/VibeNav.vue.d.ts +39 -40
- package/dist/components/VibeOffcanvas.vue.d.ts +37 -6
- package/dist/components/VibePopover.vue.d.ts +31 -5
- package/dist/components/VibeScrollspy.vue.d.ts +9 -3
- package/dist/components/VibeTabContent.vue.d.ts +13 -3
- package/dist/components/VibeToast.vue.d.ts +41 -6
- package/dist/components/VibeTooltip.vue.d.ts +31 -5
- package/dist/composables/useColorMode.d.ts +14 -0
- package/dist/composables/useId.d.ts +5 -0
- package/dist/index.d.ts +2 -0
- package/dist/types.d.ts +1 -0
- package/dist/vibeui.css +1 -1
- package/dist/vibeui.es.js +2098 -1596
- package/dist/vibeui.umd.js +1 -1
- package/package.json +4 -4
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**:
|
|
9
|
-
* **Data-Driven
|
|
10
|
-
* **
|
|
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**:
|
|
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
|
-
|
|
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
|
-
##
|
|
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
|
-
|
|
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
|
-
|
|
363
|
-
|
|
364
|
-
<
|
|
365
|
-
|
|
366
|
-
|
|
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
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
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
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
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
|
-
##
|
|
86
|
+
## Full Documentation
|
|
797
87
|
|
|
798
|
-
|
|
88
|
+
For detailed documentation and examples, visit our [Docs](./docs/README.md).
|
|
799
89
|
|
|
800
90
|
## License
|
|
801
91
|
|