@velkymx/vibeui 0.9.0 → 1.1.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/AGENTS.md +44 -0
- package/CLAUDE.md +48 -0
- package/README.md +222 -197
- package/dist/App.vue.d.ts +2 -1
- package/dist/components/HelloWorld.vue.d.ts +2 -1
- package/dist/components/VibeAccordion.vue.d.ts +39 -40
- package/dist/components/VibeAlert.vue.d.ts +21 -37
- package/dist/components/VibeAutocomplete.vue.d.ts +59 -31
- package/dist/components/VibeBadge.vue.d.ts +10 -18
- package/dist/components/VibeBreadcrumb.vue.d.ts +25 -21
- package/dist/components/VibeButton.vue.d.ts +13 -17
- package/dist/components/VibeButtonGroup.vue.d.ts +11 -19
- package/dist/components/VibeCard.vue.d.ts +51 -24
- package/dist/components/VibeCarousel.vue.d.ts +27 -49
- package/dist/components/VibeChartBar.vue.d.ts +61 -0
- package/dist/components/VibeChartLine.vue.d.ts +70 -0
- package/dist/components/VibeChartPie.vue.d.ts +34 -0
- package/dist/components/VibeCloseButton.vue.d.ts +9 -7
- package/dist/components/VibeCol.vue.d.ts +9 -17
- package/dist/components/VibeCollapse.vue.d.ts +24 -32
- package/dist/components/VibeContainer.vue.d.ts +9 -17
- package/dist/components/VibeDataTable.vue.d.ts +122 -63
- package/dist/components/VibeDatePicker.vue.d.ts +4 -6
- package/dist/components/VibeDraggable.vue.d.ts +9 -13
- package/dist/components/VibeDropdown.vue.d.ts +46 -43
- package/dist/components/VibeDroppable.vue.d.ts +9 -13
- package/dist/components/VibeFileInput.vue.d.ts +14 -20
- package/dist/components/VibeFormCheckbox.vue.d.ts +30 -22
- package/dist/components/VibeFormDatepicker.vue.d.ts +27 -30
- package/dist/components/VibeFormErrorSummary.vue.d.ts +17 -0
- package/dist/components/VibeFormGroup.vue.d.ts +10 -13
- package/dist/components/VibeFormInput.vue.d.ts +60 -25
- package/dist/components/VibeFormRadio.vue.d.ts +23 -24
- package/dist/components/VibeFormSelect.vue.d.ts +28 -34
- package/dist/components/VibeFormSpinbutton.vue.d.ts +31 -34
- package/dist/components/VibeFormSwitch.vue.d.ts +22 -23
- package/dist/components/VibeFormTextarea.vue.d.ts +24 -25
- package/dist/components/VibeFormWysiwyg.vue.d.ts +23 -22
- package/dist/components/VibeHero.vue.d.ts +117 -0
- package/dist/components/VibeIcon.vue.d.ts +27 -7
- package/dist/components/VibeInputGroup.vue.d.ts +12 -14
- package/dist/components/VibeLink.vue.d.ts +14 -18
- package/dist/components/VibeListGroup.vue.d.ts +26 -22
- package/dist/components/VibeModal.vue.d.ts +47 -45
- package/dist/components/VibeNav.vue.d.ts +40 -20
- package/dist/components/VibeNavbar.vue.d.ts +12 -19
- package/dist/components/VibeNavbarBrand.vue.d.ts +9 -17
- package/dist/components/VibeNavbarNav.vue.d.ts +52 -33
- package/dist/components/VibeNavbarToggle.vue.d.ts +7 -5
- package/dist/components/VibeOffcanvas.vue.d.ts +28 -43
- package/dist/components/VibePagination.vue.d.ts +38 -29
- package/dist/components/VibePlaceholder.vue.d.ts +9 -17
- package/dist/components/VibePopover.vue.d.ts +17 -40
- package/dist/components/VibeProgress.vue.d.ts +13 -21
- package/dist/components/VibeResizable.vue.d.ts +10 -14
- package/dist/components/VibeRow.vue.d.ts +9 -17
- package/dist/components/VibeScrollspy.vue.d.ts +37 -25
- package/dist/components/VibeSkeleton.vue.d.ts +2 -1
- package/dist/components/VibeSlider.vue.d.ts +4 -5
- package/dist/components/VibeSortable.vue.d.ts +37 -18
- package/dist/components/VibeSpinner.vue.d.ts +4 -7
- package/dist/components/VibeStepper.vue.d.ts +32 -31
- package/dist/components/VibeTab.vue.d.ts +7 -11
- package/dist/components/VibeTabContent.vue.d.ts +13 -31
- package/dist/components/VibeTabs.vue.d.ts +9 -13
- package/dist/components/VibeToast.vue.d.ts +31 -44
- package/dist/components/VibeToastHost.vue.d.ts +2 -1
- package/dist/components/VibeTooltip.vue.d.ts +16 -39
- package/dist/components/chart/chartColors.d.ts +3 -0
- package/dist/components/chart/chartResize.d.ts +2 -0
- package/dist/components/chart/chartTooltip.d.ts +2 -0
- package/dist/components/chart/chartTypes.d.ts +6 -0
- package/dist/components/chart/drawBar.d.ts +5 -0
- package/dist/components/chart/drawLine.d.ts +18 -0
- package/dist/components/chart/drawPie.d.ts +4 -0
- package/dist/components/dndStore.d.ts +1 -0
- package/dist/components/index.d.ts +6 -1
- package/dist/composables/useBreakpoints.d.ts +1 -0
- package/dist/composables/useColorMode.d.ts +1 -1
- package/dist/composables/useId.d.ts +1 -4
- package/dist/directives/vTooltip.d.ts +2 -3
- package/dist/injectionKeys.d.ts +34 -0
- package/dist/purify.es-eYghtX9j.mjs +735 -0
- package/dist/types.d.ts +23 -2
- package/dist/utils/routeKey.d.ts +11 -0
- package/dist/utils/safeCss.d.ts +16 -0
- package/dist/utils/safeHref.d.ts +7 -0
- package/dist/utils/sanitizeHtml.d.ts +13 -0
- package/dist/vibeui.css +2 -1
- package/dist/vibeui.es.js +8527 -5855
- package/dist/vibeui.umd.js +3 -1
- package/docs/README.md +225 -0
- package/docs/components/advanced/popover.md +125 -0
- package/docs/components/advanced/scrollspy.md +106 -0
- package/docs/components/advanced/tooltip.md +90 -0
- package/docs/components/card/card.md +223 -0
- package/docs/components/charts/chart-bar.md +129 -0
- package/docs/components/charts/chart-line.md +136 -0
- package/docs/components/charts/chart-pie.md +102 -0
- package/docs/components/core/alert.md +94 -0
- package/docs/components/core/badge.md +75 -0
- package/docs/components/core/button-group.md +99 -0
- package/docs/components/core/button.md +145 -0
- package/docs/components/core/close-button.md +82 -0
- package/docs/components/core/link.md +79 -0
- package/docs/components/core/placeholder.md +129 -0
- package/docs/components/core/skeleton.md +40 -0
- package/docs/components/core/spinner.md +103 -0
- package/docs/components/data/datatable.md +437 -0
- package/docs/components/hero/hero.md +65 -0
- package/docs/components/interactive/accordion.md +121 -0
- package/docs/components/interactive/carousel.md +112 -0
- package/docs/components/interactive/collapse.md +106 -0
- package/docs/components/interactive/date-picker.md +78 -0
- package/docs/components/interactive/draggable.md +91 -0
- package/docs/components/interactive/dropdown.md +129 -0
- package/docs/components/interactive/modal.md +151 -0
- package/docs/components/interactive/offcanvas.md +92 -0
- package/docs/components/interactive/resizable.md +73 -0
- package/docs/components/interactive/slider.md +57 -0
- package/docs/components/interactive/sortable.md +52 -0
- package/docs/components/interactive/stepper.md +83 -0
- package/docs/components/interactive/tabs.md +66 -0
- package/docs/components/interactive/toast.md +177 -0
- package/docs/components/layout/col.md +117 -0
- package/docs/components/layout/container.md +53 -0
- package/docs/components/layout/row.md +107 -0
- package/docs/components/list/list-group.md +225 -0
- package/docs/components/navigation/breadcrumb.md +120 -0
- package/docs/components/navigation/nav.md +151 -0
- package/docs/components/navigation/navbar.md +114 -0
- package/docs/components/navigation/pagination.md +163 -0
- package/docs/components/progress/progress.md +188 -0
- package/docs/composables/back-button.md +28 -0
- package/docs/composables/breakpoints.md +54 -0
- package/docs/composables/color-mode.md +179 -0
- package/docs/composables/use-form.md +78 -0
- package/docs/composables/use-position.md +68 -0
- package/docs/composables/use-toast.md +91 -0
- package/docs/directives/v-tooltip.md +58 -0
- package/docs/forms/README.md +87 -0
- package/docs/forms/autocomplete.md +96 -0
- package/docs/forms/file-input.md +97 -0
- package/docs/forms/form-checkbox.md +100 -0
- package/docs/forms/form-datepicker.md +80 -0
- package/docs/forms/form-error-summary.md +96 -0
- package/docs/forms/form-group.md +118 -0
- package/docs/forms/form-input.md +140 -0
- package/docs/forms/form-radio.md +82 -0
- package/docs/forms/form-select.md +98 -0
- package/docs/forms/form-spinbutton.md +94 -0
- package/docs/forms/form-switch.md +75 -0
- package/docs/forms/form-textarea.md +82 -0
- package/docs/forms/form-wysiwyg.md +99 -0
- package/docs/forms/input-group.md +70 -0
- package/docs/forms/validation.md +213 -0
- package/docs/getting-started/starter-template.md +136 -0
- package/docs/superpowers/plans/2026-05-12-vibe-charts.md +1999 -0
- package/docs/superpowers/plans/2026-05-29-e2e-browser-testing.md +615 -0
- package/docs/superpowers/specs/2026-05-12-charting-design.md +185 -0
- package/docs/superpowers/specs/2026-05-29-e2e-browser-testing-design.md +168 -0
- package/docs/utilities/position.md +82 -0
- package/docs/versioning.md +57 -0
- package/examples/README.md +201 -0
- package/examples/album.html +262 -0
- package/examples/blog.html +166 -0
- package/examples/carousel.html +114 -0
- package/examples/checkout.html +275 -0
- package/examples/cover.html +89 -0
- package/examples/dashboard.html +156 -0
- package/examples/index.html +129 -0
- package/examples/jumbotron.html +56 -0
- package/examples/mobile-dashboard.html +138 -0
- package/examples/pricing.html +172 -0
- package/examples/product.html +145 -0
- package/examples/sidebars.html +166 -0
- package/examples/sign-in.html +119 -0
- package/examples/starter.html +314 -0
- package/examples/sticky-footer-navbar.html +70 -0
- package/examples/sticky-footer.html +60 -0
- package/examples/test-simple.html +91 -0
- package/llms.txt +801 -0
- package/package.json +44 -14
- package/dist/types/index.d.ts +0 -6
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# VibeBreadcrumb
|
|
2
|
+
|
|
3
|
+
Data-driven breadcrumb navigation to indicate the current page's location within a navigational hierarchy.
|
|
4
|
+
|
|
5
|
+
## Props
|
|
6
|
+
|
|
7
|
+
| Prop | Type | Default | Description |
|
|
8
|
+
|------|------|---------|-------------|
|
|
9
|
+
| `ariaLabel` | `String` | `'breadcrumb'` | ARIA label for navigation |
|
|
10
|
+
| `items` | `BreadcrumbItem[]` | Required | Array of breadcrumb items |
|
|
11
|
+
|
|
12
|
+
### BreadcrumbItem Interface
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
interface BreadcrumbItem {
|
|
16
|
+
text: string
|
|
17
|
+
href?: string
|
|
18
|
+
to?: string | object
|
|
19
|
+
active?: boolean
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Events
|
|
24
|
+
|
|
25
|
+
| Event | Payload | Description |
|
|
26
|
+
|-------|---------|-------------|
|
|
27
|
+
| `item-click` | `{ item, index, event }` | Emitted when an item is clicked (unless active) |
|
|
28
|
+
|
|
29
|
+
## Slots
|
|
30
|
+
|
|
31
|
+
| Slot | Scope | Description |
|
|
32
|
+
|------|-------|-------------|
|
|
33
|
+
| `item` | `{ item, index }` | Custom item rendering |
|
|
34
|
+
|
|
35
|
+
## Usage
|
|
36
|
+
|
|
37
|
+
### Basic Example
|
|
38
|
+
|
|
39
|
+
```vue
|
|
40
|
+
<template>
|
|
41
|
+
<VibeBreadcrumb :items="breadcrumbItems" />
|
|
42
|
+
</template>
|
|
43
|
+
|
|
44
|
+
<script setup>
|
|
45
|
+
const breadcrumbItems = [
|
|
46
|
+
{ text: 'Home', href: '/' },
|
|
47
|
+
{ text: 'Library', href: '/library' },
|
|
48
|
+
{ text: 'Data', active: true }
|
|
49
|
+
]
|
|
50
|
+
</script>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### With Router Links
|
|
54
|
+
|
|
55
|
+
```vue
|
|
56
|
+
<template>
|
|
57
|
+
<VibeBreadcrumb :items="breadcrumbItems" />
|
|
58
|
+
</template>
|
|
59
|
+
|
|
60
|
+
<script setup>
|
|
61
|
+
const breadcrumbItems = [
|
|
62
|
+
{ text: 'Home', to: { name: 'home' } },
|
|
63
|
+
{ text: 'Products', to: { name: 'products' } },
|
|
64
|
+
{ text: 'Details', active: true }
|
|
65
|
+
]
|
|
66
|
+
</script>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Custom Item Rendering
|
|
70
|
+
|
|
71
|
+
Use the `item` scoped slot for custom rendering:
|
|
72
|
+
|
|
73
|
+
```vue
|
|
74
|
+
<template>
|
|
75
|
+
<VibeBreadcrumb :items="breadcrumbItems">
|
|
76
|
+
<template #item="{ item, index }">
|
|
77
|
+
<VibeIcon v-if="item.icon" :icon="item.icon" class="me-1" />
|
|
78
|
+
{{ item.text }}
|
|
79
|
+
</template>
|
|
80
|
+
</VibeBreadcrumb>
|
|
81
|
+
</template>
|
|
82
|
+
|
|
83
|
+
<script setup>
|
|
84
|
+
const breadcrumbItems = [
|
|
85
|
+
{ text: 'Home', href: '/', icon: 'house-fill' },
|
|
86
|
+
{ text: 'Library', href: '/library', icon: 'book' },
|
|
87
|
+
{ text: 'Data', active: true, icon: 'file-earmark' }
|
|
88
|
+
]
|
|
89
|
+
</script>
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### With Event Handling
|
|
93
|
+
|
|
94
|
+
```vue
|
|
95
|
+
<template>
|
|
96
|
+
<VibeBreadcrumb :items="breadcrumbItems" @item-click="handleClick" />
|
|
97
|
+
</template>
|
|
98
|
+
|
|
99
|
+
<script setup>
|
|
100
|
+
const breadcrumbItems = [
|
|
101
|
+
{ text: 'Home', href: '/' },
|
|
102
|
+
{ text: 'Products', href: '/products' },
|
|
103
|
+
{ text: 'Details', active: true }
|
|
104
|
+
]
|
|
105
|
+
|
|
106
|
+
const handleClick = ({ item, index }) => {
|
|
107
|
+
console.log(`Clicked: ${item.text} at index ${index}`)
|
|
108
|
+
}
|
|
109
|
+
</script>
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Important Notes
|
|
113
|
+
|
|
114
|
+
**`href` sanitization:** Item `href` values are sanitized. Only `https?://`, root-relative (`/path`), relative (`./`, `../`), and anchor (`#anchor`) URLs are allowed. `javascript:`, `data:`, and protocol-relative (`//`) URLs are stripped — such items render as plain text instead of links. Use `to` for Vue Router navigation.
|
|
115
|
+
|
|
116
|
+
## Bootstrap CSS Classes
|
|
117
|
+
|
|
118
|
+
- `.breadcrumb`
|
|
119
|
+
- `.breadcrumb-item`
|
|
120
|
+
- `.active`
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# VibeNav
|
|
2
|
+
|
|
3
|
+
Data-driven navigation tabs and pills for organizing content.
|
|
4
|
+
|
|
5
|
+
## Props
|
|
6
|
+
|
|
7
|
+
| Prop | Type | Default | Description |
|
|
8
|
+
|------|------|---------|-------------|
|
|
9
|
+
| `tabs` | `Boolean` | `false` | Use tabs style |
|
|
10
|
+
| `pills` | `Boolean` | `false` | Use pills style |
|
|
11
|
+
| `underline` | `Boolean` | `false` | Use the new Bootstrap 5.3 underline style |
|
|
12
|
+
| `fill` | `Boolean` | `false` | Fill available width proportionally |
|
|
13
|
+
| `justified` | `Boolean` | `false` | Fill available width equally |
|
|
14
|
+
| `vertical` | `Boolean` | `false` | Stack navigation vertically |
|
|
15
|
+
| `tag` | `String` | `'ul'` | HTML tag to render |
|
|
16
|
+
| `items` | `NavItem[]` | Required | Array of nav items |
|
|
17
|
+
|
|
18
|
+
### NavItem Interface
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
interface NavItem {
|
|
22
|
+
text: string
|
|
23
|
+
href?: string
|
|
24
|
+
to?: string | object
|
|
25
|
+
/** Tab panel selector (e.g. '#panel-id') for tabs/pills mode with router-link items */
|
|
26
|
+
target?: string
|
|
27
|
+
active?: boolean
|
|
28
|
+
disabled?: boolean
|
|
29
|
+
children?: NavItem[] // Support for dropdowns
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Events
|
|
34
|
+
|
|
35
|
+
| Event | Payload | Description |
|
|
36
|
+
|-------|---------|-------------|
|
|
37
|
+
| `item-click` | `{ item, index, event }` | Emitted when item is clicked |
|
|
38
|
+
| `show` | `event` | Emitted when a tab starts showing |
|
|
39
|
+
| `shown` | `event` | Emitted when a tab is fully shown |
|
|
40
|
+
| `hide` | `event` | Emitted when a tab starts hiding |
|
|
41
|
+
| `hidden` | `event` | Emitted when a tab is fully hidden |
|
|
42
|
+
|
|
43
|
+
## Slots
|
|
44
|
+
|
|
45
|
+
| Slot | Scope | Description |
|
|
46
|
+
|------|-------|-------------|
|
|
47
|
+
| `item` | `{ item, index }` | Custom item rendering |
|
|
48
|
+
|
|
49
|
+
## Usage
|
|
50
|
+
|
|
51
|
+
### Custom item content (`#item` slot)
|
|
52
|
+
|
|
53
|
+
Use the `item` slot to render richer nav links — e.g. an icon next to the label. The slot is scoped with `{ item, index }`.
|
|
54
|
+
|
|
55
|
+
```vue
|
|
56
|
+
<template>
|
|
57
|
+
<VibeNav :items="navItems">
|
|
58
|
+
<template #item="{ item }">
|
|
59
|
+
<VibeIcon :icon="item.icon" class="me-2" />
|
|
60
|
+
{{ item.text }}
|
|
61
|
+
</template>
|
|
62
|
+
</VibeNav>
|
|
63
|
+
</template>
|
|
64
|
+
|
|
65
|
+
<script setup>
|
|
66
|
+
const navItems = [
|
|
67
|
+
{ text: 'Home', href: '#', icon: 'house', active: true },
|
|
68
|
+
{ text: 'Profile', href: '#', icon: 'person' }
|
|
69
|
+
]
|
|
70
|
+
</script>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Interactive Tabs
|
|
74
|
+
|
|
75
|
+
When using the `tabs` or `pills` props, nav links with an `href` starting with `#` will automatically act as Bootstrap tab triggers.
|
|
76
|
+
|
|
77
|
+
```vue
|
|
78
|
+
<template>
|
|
79
|
+
<div>
|
|
80
|
+
<VibeNav tabs :items="navItems" />
|
|
81
|
+
|
|
82
|
+
<VibeTabContent :panes="tabPanes" class="mt-3" />
|
|
83
|
+
</div>
|
|
84
|
+
</template>
|
|
85
|
+
|
|
86
|
+
<script setup>
|
|
87
|
+
const navItems = [
|
|
88
|
+
{ text: 'Home', href: '#home', active: true },
|
|
89
|
+
{ text: 'Profile', href: '#profile' }
|
|
90
|
+
]
|
|
91
|
+
|
|
92
|
+
const tabPanes = [
|
|
93
|
+
{ id: 'home', content: 'Home content...', active: true },
|
|
94
|
+
{ id: 'profile', content: 'Profile content...' }
|
|
95
|
+
]
|
|
96
|
+
</script>
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Tabs with Vue Router Links
|
|
100
|
+
|
|
101
|
+
Items using `to` (router-link) also work in tabs/pills mode. Provide a `target` field pointing to the panel ID, and Bootstrap Tab events (`show`, `shown`, `hide`, `hidden`) will fire correctly:
|
|
102
|
+
|
|
103
|
+
```vue
|
|
104
|
+
<template>
|
|
105
|
+
<VibeNav tabs :items="navItems" @shown="onShown" />
|
|
106
|
+
<div class="tab-content mt-3">
|
|
107
|
+
<div id="overview-pane" class="tab-pane fade show active">Overview content</div>
|
|
108
|
+
<div id="settings-pane" class="tab-pane fade">Settings content</div>
|
|
109
|
+
</div>
|
|
110
|
+
</template>
|
|
111
|
+
|
|
112
|
+
<script setup>
|
|
113
|
+
const navItems = [
|
|
114
|
+
{ text: 'Overview', to: '/overview', target: '#overview-pane', active: true },
|
|
115
|
+
{ text: 'Settings', to: '/settings', target: '#settings-pane' }
|
|
116
|
+
]
|
|
117
|
+
|
|
118
|
+
const onShown = (event) => {
|
|
119
|
+
console.log('Tab shown:', event.target)
|
|
120
|
+
}
|
|
121
|
+
</script>
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Items with `to` starting with `#` are also treated as tab targets without needing an explicit `target` field.
|
|
125
|
+
|
|
126
|
+
## Exposed Methods
|
|
127
|
+
|
|
128
|
+
| Method | Description |
|
|
129
|
+
|--------|-------------|
|
|
130
|
+
| `refresh()` | Tears down and re-initializes Bootstrap Tab instances. Call after dynamically changing items if needed. |
|
|
131
|
+
|
|
132
|
+
> **Escape hatch:** `_unsafe_bsInstances` (a `Map` of the underlying Bootstrap `Tab` instances) is also exposed. It is **not** part of the stable API — calling `dispose()` or other lifecycle methods on these directly WILL break the component.
|
|
133
|
+
|
|
134
|
+
## Important Notes
|
|
135
|
+
|
|
136
|
+
**`href` sanitization:** Item and child `href` values are sanitized. Only `https?://`, root-relative (`/path`), relative (`./`, `../`), and anchor (`#anchor`) URLs are allowed; `javascript:`, `data:`, and protocol-relative (`//`) URLs are stripped. Use `to` for Vue Router navigation.
|
|
137
|
+
|
|
138
|
+
**Disabled button items:** Items without `href` or `to` (plain button items) receive the HTML `disabled` attribute when `disabled: true` is set. Link and router-link items only get the disabled visual style — the browser attribute is omitted because `<a disabled>` has no native effect.
|
|
139
|
+
|
|
140
|
+
**Automatic Initialization:** When using `tabs` or `pills`, this component automatically initializes Bootstrap's Tab functionality for items that target a local panel ID via `href="#..."`, `target="#..."`, or `to="#..."`.
|
|
141
|
+
|
|
142
|
+
**State Management:** For complex tab state, combine `VibeNav` with `VibeTabContent` and manage the `active` state through your data.
|
|
143
|
+
|
|
144
|
+
## Bootstrap CSS Classes
|
|
145
|
+
|
|
146
|
+
- `.nav`
|
|
147
|
+
- `.nav-tabs`
|
|
148
|
+
- `.nav-pills`
|
|
149
|
+
- `.nav-underline`
|
|
150
|
+
- `.nav-item`
|
|
151
|
+
- `.nav-link`
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# Navbar Components
|
|
2
|
+
|
|
3
|
+
Responsive navigation header with support for branding, navigation, and collapsible content.
|
|
4
|
+
|
|
5
|
+
## VibeNavbar
|
|
6
|
+
|
|
7
|
+
Main navbar container. Provides reactive collapse state to child components via Vue's provide/inject.
|
|
8
|
+
|
|
9
|
+
### Props
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Default | Description |
|
|
12
|
+
|------|------|---------|-------------|
|
|
13
|
+
| `variant` | `Variant\|'dark'\|'light'` | `'light'` | Background color: maps to `bg-{variant}` |
|
|
14
|
+
| `theme` | `'dark'\|'light'` | auto | Color scheme applied via `data-bs-theme`. Defaults to `'dark'` when `variant='dark'`, `'light'` when `variant='light'`, otherwise unset |
|
|
15
|
+
| `expand` | `Boolean\|String` | `'lg'` | Breakpoint for collapse: `'sm'`, `'md'`, `'lg'`, `'xl'`, or `true` for always expanded |
|
|
16
|
+
| `container` | `Boolean\|String` | `true` | Container type: `true` for fluid, or `'sm'`, `'md'`, `'lg'`, `'xl'` |
|
|
17
|
+
| `position` | `NavbarPosition` | `undefined` | Position: `'fixed-top'`, `'fixed-bottom'`, `'sticky-top'` |
|
|
18
|
+
| `tag` | `String` | `'nav'` | HTML tag to render |
|
|
19
|
+
|
|
20
|
+
## Sub-Components
|
|
21
|
+
|
|
22
|
+
### VibeNavbarBrand
|
|
23
|
+
Branding/logo section
|
|
24
|
+
|
|
25
|
+
#### Props
|
|
26
|
+
|
|
27
|
+
| Prop | Type | Default | Description |
|
|
28
|
+
|------|------|---------|-------------|
|
|
29
|
+
| `href` | `String` | `undefined` | Link URL (renders as `<a>`) |
|
|
30
|
+
| `to` | `String\|Object` | `undefined` | Router link target (renders as `<router-link>`) |
|
|
31
|
+
|
|
32
|
+
### VibeNavbarToggle
|
|
33
|
+
Mobile collapse toggle button.
|
|
34
|
+
|
|
35
|
+
#### Props
|
|
36
|
+
|
|
37
|
+
| Prop | Type | Default | Description |
|
|
38
|
+
|------|------|---------|-------------|
|
|
39
|
+
| `target` | `String` | Required | The `id` of the `VibeCollapse` to toggle |
|
|
40
|
+
| `ariaLabel` | `String` | `'Toggle navigation'` | Accessible label for the button |
|
|
41
|
+
|
|
42
|
+
#### Events
|
|
43
|
+
|
|
44
|
+
| Event | Payload | Description |
|
|
45
|
+
|-------|---------|-------------|
|
|
46
|
+
| `component-error` | `ComponentError` | Emitted if the Bootstrap collapse toggle fails (e.g. Bootstrap JS unavailable) |
|
|
47
|
+
|
|
48
|
+
### VibeNavbarNav
|
|
49
|
+
Navigation links container. Supports regular links and dropdown items.
|
|
50
|
+
|
|
51
|
+
#### Props
|
|
52
|
+
|
|
53
|
+
| Prop | Type | Default | Description |
|
|
54
|
+
|------|------|---------|-------------|
|
|
55
|
+
| `tag` | `String` | `'ul'` | HTML tag to render |
|
|
56
|
+
| `items` | `NavItem[]` | `undefined` | Array of nav items (data-driven mode) |
|
|
57
|
+
|
|
58
|
+
#### Events
|
|
59
|
+
|
|
60
|
+
| Event | Payload | Description |
|
|
61
|
+
|-------|---------|-------------|
|
|
62
|
+
| `item-click` | `{ item, index, event }` | Emitted when a regular nav item is clicked |
|
|
63
|
+
| `dropdown-item-click` | `{ item, itemIndex, child, childIndex, event }` | Emitted when a dropdown child item is clicked |
|
|
64
|
+
|
|
65
|
+
## Usage
|
|
66
|
+
|
|
67
|
+
### Basic Navbar
|
|
68
|
+
|
|
69
|
+
```vue
|
|
70
|
+
<template>
|
|
71
|
+
<VibeNavbar variant="light" expand="lg">
|
|
72
|
+
<VibeNavbarBrand href="#">Navbar</VibeNavbarBrand>
|
|
73
|
+
<VibeNavbarToggle target="navbarNav" />
|
|
74
|
+
<VibeCollapse id="navbarNav" is-nav>
|
|
75
|
+
<VibeNavbarNav :items="navItems" />
|
|
76
|
+
</VibeCollapse>
|
|
77
|
+
</VibeNavbar>
|
|
78
|
+
</template>
|
|
79
|
+
|
|
80
|
+
<script setup>
|
|
81
|
+
const navItems = [
|
|
82
|
+
{ text: 'Home', href: '#', active: true },
|
|
83
|
+
{ text: 'Features', href: '#' },
|
|
84
|
+
{ text: 'Pricing', href: '#' }
|
|
85
|
+
]
|
|
86
|
+
</script>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Important Notes
|
|
90
|
+
|
|
91
|
+
**`href` sanitization:** `VibeNavbarBrand` (and `VibeNavbarNav` items) sanitize `href` values. Only `https?://`, root-relative (`/path`), relative (`./`, `../`), and anchor (`#anchor`) URLs are allowed; `javascript:`, `data:`, and protocol-relative (`//`) URLs are stripped. Use `to` for Vue Router navigation.
|
|
92
|
+
|
|
93
|
+
**Automatic Synchronization:** `VibeNavbarToggle` is refactored to ensure that clicking it updates both Vue's internal state and the underlying Bootstrap `Collapse` instance simultaneously.
|
|
94
|
+
|
|
95
|
+
**Smooth Transitions:** `VibeCollapse` now utilizes Bootstrap's JavaScript engine by default, providing smooth sliding animations when toggled via the navbar.
|
|
96
|
+
|
|
97
|
+
**State Management:** Even when using Bootstrap JS for animations, the navbar remains fully reactive. You can still control the collapse state programmatically via the `VibeCollapse` `v-model`.
|
|
98
|
+
|
|
99
|
+
## Mobile & Hybrid Optimization
|
|
100
|
+
|
|
101
|
+
**Safe Areas:** When using `position="fixed-top"`, `fixed-bottom"`, or `sticky-top"`, the navbar automatically adds padding to account for device safe areas (notches) in hybrid environments like Capacitor.
|
|
102
|
+
|
|
103
|
+
## Bootstrap CSS Classes
|
|
104
|
+
|
|
105
|
+
- `.navbar`
|
|
106
|
+
- `.navbar-expand-{breakpoint}`
|
|
107
|
+
- `.bg-{variant}`
|
|
108
|
+
- `data-bs-theme="dark|light"`
|
|
109
|
+
- `.navbar-brand`
|
|
110
|
+
- `.navbar-toggler`
|
|
111
|
+
- `.navbar-nav`
|
|
112
|
+
- `.navbar-collapse`
|
|
113
|
+
- `.nav-item`
|
|
114
|
+
- `.nav-link`
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# VibePagination
|
|
2
|
+
|
|
3
|
+
Data-driven pagination component with v-model support.
|
|
4
|
+
|
|
5
|
+
## Props
|
|
6
|
+
|
|
7
|
+
| Prop | Type | Default | Description |
|
|
8
|
+
|------|------|---------|-------------|
|
|
9
|
+
| `size` | `'sm' \| 'lg'` | `undefined` | Pagination size |
|
|
10
|
+
| `ariaLabel` | `String` | `'Pagination'` | ARIA label for the nav element |
|
|
11
|
+
| `totalPages` | `Number` | Required | Total number of pages |
|
|
12
|
+
| `currentPage` | `Number` | `1` | Current active page |
|
|
13
|
+
| `showPrevNext` | `Boolean` | `true` | Show previous/next buttons |
|
|
14
|
+
| `prevText` | `String` | `'Previous'` | Text for previous button |
|
|
15
|
+
| `nextText` | `String` | `'Next'` | Text for next button |
|
|
16
|
+
| `maxVisiblePages` | `Number` | `7` | Maximum page buttons to show before collapsing to ellipsis |
|
|
17
|
+
|
|
18
|
+
## Events
|
|
19
|
+
|
|
20
|
+
| Event | Payload | Description |
|
|
21
|
+
|-------|---------|-------------|
|
|
22
|
+
| `update:currentPage` | `page: number` | Emitted when page changes (v-model) |
|
|
23
|
+
| `page-click` | `page: number` | Emitted when a page is clicked |
|
|
24
|
+
| `component-error` | `ComponentError` | Emitted if an internal error occurs |
|
|
25
|
+
|
|
26
|
+
## Slots
|
|
27
|
+
|
|
28
|
+
| Slot | Scope | Description |
|
|
29
|
+
|------|-------|-------------|
|
|
30
|
+
| `prev` | `{ disabled }` | Custom previous button |
|
|
31
|
+
| `page` | `{ page, active }` | Custom page button |
|
|
32
|
+
| `next` | `{ disabled }` | Custom next button |
|
|
33
|
+
|
|
34
|
+
## Usage
|
|
35
|
+
|
|
36
|
+
### Basic Example
|
|
37
|
+
|
|
38
|
+
```vue
|
|
39
|
+
<template>
|
|
40
|
+
<VibePagination
|
|
41
|
+
:total-pages="10"
|
|
42
|
+
v-model:current-page="currentPage"
|
|
43
|
+
/>
|
|
44
|
+
</template>
|
|
45
|
+
|
|
46
|
+
<script setup>
|
|
47
|
+
import { ref } from 'vue'
|
|
48
|
+
|
|
49
|
+
const currentPage = ref(1)
|
|
50
|
+
</script>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Sizes
|
|
54
|
+
|
|
55
|
+
```vue
|
|
56
|
+
<template>
|
|
57
|
+
<!-- Small -->
|
|
58
|
+
<VibePagination :total-pages="5" size="sm" v-model:current-page="page1" />
|
|
59
|
+
|
|
60
|
+
<!-- Default -->
|
|
61
|
+
<VibePagination :total-pages="5" v-model:current-page="page2" />
|
|
62
|
+
|
|
63
|
+
<!-- Large -->
|
|
64
|
+
<VibePagination :total-pages="5" size="lg" v-model:current-page="page3" />
|
|
65
|
+
</template>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Without Prev/Next Buttons
|
|
69
|
+
|
|
70
|
+
```vue
|
|
71
|
+
<template>
|
|
72
|
+
<VibePagination
|
|
73
|
+
:total-pages="10"
|
|
74
|
+
:show-prev-next="false"
|
|
75
|
+
v-model:current-page="currentPage"
|
|
76
|
+
/>
|
|
77
|
+
</template>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Custom Button Text
|
|
81
|
+
|
|
82
|
+
```vue
|
|
83
|
+
<template>
|
|
84
|
+
<VibePagination
|
|
85
|
+
:total-pages="10"
|
|
86
|
+
prev-text="← Back"
|
|
87
|
+
next-text="Forward →"
|
|
88
|
+
v-model:current-page="currentPage"
|
|
89
|
+
/>
|
|
90
|
+
</template>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Large Page Counts (Ellipsis)
|
|
94
|
+
|
|
95
|
+
When `totalPages` exceeds `maxVisiblePages`, intermediate pages are replaced with ellipsis (`…`). First and last pages are always shown, and the window of visible pages tracks the current page.
|
|
96
|
+
|
|
97
|
+
```vue
|
|
98
|
+
<template>
|
|
99
|
+
<!-- 100 pages, only 7 buttons max — ellipsis collapses the rest -->
|
|
100
|
+
<VibePagination
|
|
101
|
+
:total-pages="100"
|
|
102
|
+
v-model:current-page="currentPage"
|
|
103
|
+
:max-visible-pages="7"
|
|
104
|
+
/>
|
|
105
|
+
</template>
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Custom Page Rendering
|
|
109
|
+
|
|
110
|
+
Use scoped slots for complete customization:
|
|
111
|
+
|
|
112
|
+
```vue
|
|
113
|
+
<template>
|
|
114
|
+
<VibePagination :total-pages="10" v-model:current-page="currentPage">
|
|
115
|
+
<template #prev="{ disabled }">
|
|
116
|
+
<VibeIcon icon="chevron-left" />
|
|
117
|
+
</template>
|
|
118
|
+
|
|
119
|
+
<template #page="{ page, active }">
|
|
120
|
+
Page {{ page }}
|
|
121
|
+
</template>
|
|
122
|
+
|
|
123
|
+
<template #next="{ disabled }">
|
|
124
|
+
<VibeIcon icon="chevron-right" />
|
|
125
|
+
</template>
|
|
126
|
+
</VibePagination>
|
|
127
|
+
</template>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### With Event Handling
|
|
131
|
+
|
|
132
|
+
```vue
|
|
133
|
+
<template>
|
|
134
|
+
<VibePagination
|
|
135
|
+
:total-pages="20"
|
|
136
|
+
v-model:current-page="currentPage"
|
|
137
|
+
@page-click="handlePageClick"
|
|
138
|
+
/>
|
|
139
|
+
|
|
140
|
+
<p>Current page: {{ currentPage }}</p>
|
|
141
|
+
</template>
|
|
142
|
+
|
|
143
|
+
<script setup>
|
|
144
|
+
import { ref } from 'vue'
|
|
145
|
+
|
|
146
|
+
const currentPage = ref(1)
|
|
147
|
+
|
|
148
|
+
const handlePageClick = (page) => {
|
|
149
|
+
console.log(`Navigated to page ${page}`)
|
|
150
|
+
// Fetch data for the new page
|
|
151
|
+
}
|
|
152
|
+
</script>
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Bootstrap CSS Classes
|
|
156
|
+
|
|
157
|
+
- `.pagination`
|
|
158
|
+
- `.pagination-sm`
|
|
159
|
+
- `.pagination-lg`
|
|
160
|
+
- `.page-item`
|
|
161
|
+
- `.page-link`
|
|
162
|
+
- `.active`
|
|
163
|
+
- `.disabled`
|