Skip to content
This repository was archived by the owner on Mar 27, 2025. It is now read-only.

Commit a17bd0e

Browse files
committed
Merge branch 'main' into feature/b-close-button-customization
2 parents 2fcc8ea + 9497c12 commit a17bd0e

File tree

14 files changed

+177
-59
lines changed

14 files changed

+177
-59
lines changed

.release-please-manifest.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
2-
"packages/bootstrap-vue-next": "0.9.20",
2+
"packages/bootstrap-vue-next": "0.9.23",
33
"packages/nuxt": "0.1.3"
44
}

apps/docs/.vitepress/config.ts

+13-3
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,25 @@
11
import {defineConfig} from 'vitepress'
22
import Icons from 'unplugin-icons/vite'
33

4+
const title = 'BootstrapVueNext'
5+
const description = 'Quickly and Easily Integrate Bootstrap V5 Components With Vue 3'
6+
47
// https://vitepress.dev/reference/site-config
58
export default defineConfig({
6-
title: 'BootstrapVueNext',
7-
description: 'BootstrapVueNext Documentation',
9+
title,
10+
description,
811
base: '/bootstrap-vue-next/',
912
srcDir: 'src',
1013
// TODO fix & remove this
1114
ignoreDeadLinks: true,
12-
head: [['link', {rel: 'icon', type: 'image/x-icon', href: '/bootstrap-vue-next/favicon.ico'}]],
15+
head: [
16+
['link', {rel: 'icon', type: 'image/x-icon', href: '/bootstrap-vue-next/favicon.ico'}],
17+
['meta', {property: 'og:title', name: 'og:title', content: title}],
18+
['meta', {property: 'og:description', name: 'og:description', content: description}],
19+
['meta', {property: 'twitter:card', name: 'twitter:card', content: 'summary'}],
20+
['meta', {property: 'twitter:title', name: 'twitter:title', content: title}],
21+
['meta', {property: 'twitter:description', name: 'twitter:description', content: description}],
22+
],
1323
vite: {
1424
plugins: [Icons()],
1525
},

apps/docs/.vitepress/theme/Layout.vue

+14-17
Original file line numberDiff line numberDiff line change
@@ -34,43 +34,41 @@
3434
</BNavbarNav>
3535
</BCollapse>
3636
<BNav>
37-
<BButton
38-
:variant="null"
37+
<BNavItem
3938
:href="globalData.githubUrl"
40-
aria-label="Open Github"
39+
:link-attrs="{'aria-label': 'Open Our Github'}"
4140
target="_blank"
4241
rel="noopener"
4342
>
4443
<GithubIcon aria-hidden />
45-
</BButton>
46-
<BButton
47-
:variant="null"
44+
</BNavItem>
45+
<BNavItem
4846
:href="globalData.opencollectiveUrl"
49-
aria-label="Open Github"
47+
:link-attrs="{'aria-label': 'Open Our Opencollective'}"
5048
target="_blank"
5149
rel="noopener"
5250
>
5351
<OpencollectiveIcon />
54-
</BButton>
55-
<BButton
56-
:variant="null"
52+
</BNavItem>
53+
<BNavItem
5754
:href="globalData.discordUrl"
58-
aria-label="Open Discord Server"
55+
:link-attrs="{'aria-label': 'Open Our Discord Server'}"
56+
aria-label=""
5957
target="_blank"
6058
rel="noopener"
6159
>
6260
<DiscordIcon aria-hidden />
63-
</BButton>
61+
</BNavItem>
6462
<ClientOnly>
65-
<BDropdown :variant="null">
63+
<BNavItemDropdown>
6664
<!-- TODO there's no way to adjust these options, say if you wanted to remove the padding -->
6765
<template #button-content>
6866
<component :is="currentIcon" :aria-label="`Toggle theme (${dark})`" />
6967
</template>
7068
<BDropdownItem v-for="el in options" :key="el" :active="dark === el" @click="set(el)">
7169
<component :is="map[el]" /> {{ el }}
7270
</BDropdownItem>
73-
</BDropdown>
71+
</BNavItemDropdown>
7472
</ClientOnly>
7573
</BNav>
7674
<BNavbarToggle v-b-toggle.otp-menu class="otp-menu-toggle">
@@ -137,11 +135,10 @@
137135

138136
<script setup lang="ts">
139137
import {
140-
BButton,
141138
BCol,
142139
BCollapse,
143140
BContainer,
144-
BDropdown,
141+
BNavItemDropdown,
145142
BDropdownItem,
146143
BNav,
147144
BNavbar,
@@ -162,7 +159,7 @@ import MoonStarsFill from '~icons/bi/moon-stars-fill'
162159
import SunFill from '~icons/bi/sun-fill'
163160
import ChevronRight from '~icons/bi/chevron-right'
164161
import CircleHalf from '~icons/bi/circle-half'
165-
import {useData, withBase, useRoute} from 'vitepress'
162+
import {useData, useRoute, withBase} from 'vitepress'
166163
import {appInfoKey} from './keys'
167164
import {useMediaQuery} from '@vueuse/core'
168165
import TableOfContentsNav from '../../src/components/TableOfContentsNav.vue'

apps/docs/src/index.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ With more than 35 components, several directives and composibles (and growing),
4848

4949
<div class="d-flex gap-2 mt-4">
5050
<BButton :to="withBase('/docs')" variant="primary">Get Started</BButton>
51-
<BButton :href="globalData.githubUrl" target="_blank" aria-label="Open Github" rel="noopener" variant="outline-secondary">GitHub</BButton>
51+
<BButton :href="globalData.githubUrl" target="_blank" rel="noopener" variant="outline-secondary">GitHub</BButton>
5252
</div>
5353

5454
## Integrate with Nuxt.js

packages/bootstrap-vue-next/CHANGELOG.md

+27
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,33 @@
11
# Changelog
22

33

4+
## [0.9.23](https://github.com/bootstrap-vue-next/bootstrap-vue-next/compare/bootstrap-vue-next-v0.9.22...bootstrap-vue-next-v0.9.23) (2023-07-08)
5+
6+
7+
### Features
8+
9+
* **BNavItem:** add prop linkAttrs so you can add specific attributes to the link that aren't included as props ([14d1ebf](https://github.com/bootstrap-vue-next/bootstrap-vue-next/commit/14d1ebfbc533e8a9217465d117e0a50978987b77))
10+
11+
12+
### Bug Fixes
13+
14+
* **BOffcanvas:** Aria enhancements -- multiple Offcanvas causes duplicate id ([e8bcda5](https://github.com/bootstrap-vue-next/bootstrap-vue-next/commit/e8bcda5260d62c87b03f44e6e03fb9ce991cdb6d))
15+
* replace some instances of TS 'as' with 'satisfies' ([14d1ebf](https://github.com/bootstrap-vue-next/bootstrap-vue-next/commit/14d1ebfbc533e8a9217465d117e0a50978987b77))
16+
17+
## [0.9.22](https://github.com/bootstrap-vue-next/bootstrap-vue-next/compare/bootstrap-vue-next-v0.9.21...bootstrap-vue-next-v0.9.22) (2023-07-07)
18+
19+
20+
### Features
21+
22+
* **BAvatar:** link and router support. ([ba06fa2](https://github.com/bootstrap-vue-next/bootstrap-vue-next/commit/ba06fa2d985cab7232602d0b97a3077099c84802))
23+
24+
## [0.9.21](https://github.com/bootstrap-vue-next/bootstrap-vue-next/compare/bootstrap-vue-next-v0.9.20...bootstrap-vue-next-v0.9.21) (2023-07-06)
25+
26+
27+
### Bug Fixes
28+
29+
* **package:** EXPORTS_TYPES_SHOULD_BE_FIRST ([5dbf5b8](https://github.com/bootstrap-vue-next/bootstrap-vue-next/commit/5dbf5b8ab31360962b7cc5cc629ee8f4f02b63b0))
30+
431
## [0.9.20](https://github.com/bootstrap-vue-next/bootstrap-vue-next/compare/bootstrap-vue-next-v0.9.19...bootstrap-vue-next-v0.9.20) (2023-07-04)
532

633

packages/bootstrap-vue-next/package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22
"name": "bootstrap-vue-next",
33
"displayName": "BootstrapVueNext",
44
"description": "Early (but lovely) implementation of Vue 3, Bootstrap 5 and Typescript",
5-
"version": "0.9.20",
5+
"version": "0.9.23",
66
"license": "MIT",
77
"main": "./dist/bootstrap-vue-next.umd.js",
88
"module": "./dist/bootstrap-vue-next.mjs",
99
"exports": {
1010
".": {
11+
"types": "./dist/src/BootstrapVue.d.ts",
1112
"import": "./dist/bootstrap-vue-next.mjs",
12-
"require": "./dist/bootstrap-vue-next.umd.js",
13-
"types": "./dist/src/BootstrapVue.d.ts"
13+
"require": "./dist/bootstrap-vue-next.umd.js"
1414
},
1515
"./dist/bootstrap-vue-next.css": "./dist/bootstrap-vue-next.css",
1616
"./src/styles/styles.scss": "./src/styles/styles.scss"

packages/bootstrap-vue-next/src/components/BAccordion/BAccordionItem.vue

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
v-model="modelValue"
66
class="accordion-collapse"
77
v-bind="$attrs"
8-
:aria-labelledby="`heading${computedId}`"
8+
:aria-labelledby="`${computedId}-heading`"
99
:tag="tag"
1010
:toggle="toggle"
1111
:horizontal="horizontal"
@@ -14,7 +14,7 @@
1414
v-on="events"
1515
>
1616
<template #header="{visible: toggleVisible, toggle: slotToggle}">
17-
<component :is="headerTag" :id="`heading${computedId}`" class="accordion-header">
17+
<component :is="headerTag" :id="`${computedId}-heading`" class="accordion-header">
1818
<button
1919
class="accordion-button"
2020
:class="{collapsed: !toggleVisible}"

packages/bootstrap-vue-next/src/components/BAccordion/accordion-item.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ describe('accordion-item', () => {
8080
props: {id: 'foobar'},
8181
})
8282
const [, $bcollapse] = wrapper.findComponent(BCollapse).findAll('*')
83-
expect($bcollapse.attributes('aria-labelledby')).toBe('headingfoobar')
83+
expect($bcollapse.attributes('aria-labelledby')).toBe('foobar-heading')
8484
})
8585

8686
it('headerTag is h2 by default', () => {
@@ -114,7 +114,7 @@ describe('accordion-item', () => {
114114
props: {id: 'foobar'},
115115
})
116116
const $h2 = wrapper.get('h2')
117-
expect($h2.attributes('id')).toBe('headingfoobar')
117+
expect($h2.attributes('id')).toBe('foobar-heading')
118118
})
119119

120120
it('h2 child has button child', () => {

packages/bootstrap-vue-next/src/components/BAvatar/BAvatar.vue

+80-24
Original file line numberDiff line numberDiff line change
@@ -24,32 +24,43 @@
2424
</template>
2525

2626
<script setup lang="ts">
27-
import {avatarGroupInjectionKey, isEmptySlot, isNumeric, toFloat} from '../../utils'
27+
import {
28+
avatarGroupInjectionKey,
29+
isEmptySlot,
30+
isLink,
31+
isNumeric,
32+
pluckProps,
33+
toFloat,
34+
} from '../../utils'
2835
import {computed, type CSSProperties, inject, type StyleValue, useSlots} from 'vue'
2936
import type {Booleanish, ButtonType, ColorVariant, Size, TextColorVariant} from '../../types'
3037
import {useBooleanish} from '../../composables'
38+
import BLink from '../BLink/BLink.vue'
39+
import type {BLinkProps} from '../../types/BLinkProps'
3140
3241
const props = withDefaults(
33-
defineProps<{
34-
alt?: string
35-
ariaLabel?: string
36-
badge?: boolean | string
37-
badgeLeft?: Booleanish
38-
badgeOffset?: string
39-
badgeTop?: Booleanish
40-
badgeVariant?: ColorVariant | null
41-
button?: Booleanish
42-
buttonType?: ButtonType
43-
disabled?: Booleanish
44-
icon?: string
45-
rounded?: boolean | string
46-
size?: Size | string // TODO number --> compat
47-
square?: Booleanish
48-
src?: string
49-
text?: string
50-
textVariant?: TextColorVariant | null
51-
variant?: ColorVariant | null
52-
}>(),
42+
defineProps<
43+
{
44+
alt?: string
45+
ariaLabel?: string
46+
badge?: boolean | string
47+
badgeLeft?: Booleanish
48+
badgeOffset?: string
49+
badgeTop?: Booleanish
50+
badgeVariant?: ColorVariant | null
51+
button?: Booleanish
52+
buttonType?: ButtonType
53+
disabled?: Booleanish
54+
icon?: string
55+
rounded?: boolean | string
56+
size?: Size | string // TODO number --> compat
57+
square?: Booleanish
58+
src?: string
59+
text?: string
60+
textVariant?: TextColorVariant | null
61+
variant?: ColorVariant | null
62+
} & Omit<BLinkProps, 'event' | 'routerTag'>
63+
>(),
5364
{
5465
ariaLabel: undefined,
5566
badgeOffset: undefined,
@@ -69,6 +80,25 @@ const props = withDefaults(
6980
rounded: 'circle',
7081
square: false,
7182
variant: 'secondary',
83+
// Link props
84+
active: undefined,
85+
activeClass: 'router-link-active',
86+
append: false,
87+
href: undefined,
88+
// noPrefetch: {type: [Boolean, String] as PropType<Booleanish>, default: false},
89+
// prefetch: {type: [Boolean, String] as PropType<Booleanish>, default: null},
90+
rel: undefined,
91+
replace: false,
92+
routerComponentName: 'router-link',
93+
target: '_self',
94+
to: undefined,
95+
opacity: undefined,
96+
opacityHover: undefined,
97+
underlineVariant: null,
98+
underlineOffset: undefined,
99+
underlineOffsetHover: undefined,
100+
underlineOpacity: undefined,
101+
underlineOpacityHover: undefined,
72102
}
73103
)
74104
@@ -103,6 +133,8 @@ const hasBadgeSlot = computed(() => !isEmptySlot(slots.badge))
103133
104134
const showBadge = computed<boolean>(() => !!props.badge || props.badge === '' || hasBadgeSlot.value)
105135
136+
const computedLink = computed<boolean>(() => isLink(props))
137+
106138
const computedSize = computed<string | null>(
107139
() => parentData?.size.value ?? computeSize(props.size)
108140
)
@@ -114,9 +146,31 @@ const computedVariant = computed<ColorVariant | null>(
114146
const computedRounded = computed<string | boolean>(() => parentData?.rounded.value ?? props.rounded)
115147
116148
const computedAttrs = computed(() => ({
117-
'type': buttonBoolean.value ? props.buttonType : undefined,
149+
'type': buttonBoolean.value && !computedLink.value ? props.buttonType : undefined,
118150
'aria-label': props.ariaLabel || null,
119151
'disabled': disabledBoolean.value || null,
152+
// Link props
153+
...(computedLink.value
154+
? pluckProps(props, {
155+
active: true,
156+
activeClass: true,
157+
append: true,
158+
href: true,
159+
rel: true,
160+
replace: true,
161+
routerComponentName: true,
162+
target: true,
163+
to: true,
164+
variant: true,
165+
opacity: true,
166+
opacityHover: true,
167+
underlineVariant: true,
168+
underlineOffset: true,
169+
underlineOffsetHover: true,
170+
underlineOpacity: true,
171+
underlineOpacityHover: true,
172+
} as Record<keyof Omit<BLinkProps, 'event' | 'routerTag'>, true>)
173+
: {}),
120174
}))
121175
122176
const badgeClasses = computed(() => ({
@@ -185,7 +239,9 @@ const marginStyle = computed(() => {
185239
return value ? {marginLeft: value, marginRight: value} : {}
186240
})
187241
188-
const computedTag = computed<'button' | 'span'>(() => (buttonBoolean.value ? 'button' : 'span'))
242+
const computedTag = computed<typeof BLink | 'button' | 'span'>(() =>
243+
computedLink.value ? BLink : buttonBoolean.value ? 'button' : 'span'
244+
)
189245
190246
const computedStyle = computed<CSSProperties>(() => ({
191247
...marginStyle.value,
@@ -197,7 +253,7 @@ const computeContrastVariant = (colorVariant: ColorVariant): 'dark' | 'light' =>
197253
colorVariant === 'light' || colorVariant === 'warning' ? 'dark' : 'light'
198254
199255
const clicked = (e: MouseEvent): void => {
200-
if (!disabledBoolean.value && buttonBoolean.value) emit('click', e)
256+
if (!disabledBoolean.value && (computedLink.value || buttonBoolean.value)) emit('click', e)
201257
}
202258
203259
const onImgError = (e: Event): void => emit('img-error', e)

packages/bootstrap-vue-next/src/components/BBadge/BBadge.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ const computedLinkProps = computed(() =>
101101
underlineOpacity: true,
102102
underlineOpacityHover: true,
103103
icon: true,
104-
} as Record<keyof Omit<BLinkProps, 'event' | 'routerTag'>, true>)
104+
} satisfies Record<keyof Omit<BLinkProps, 'event' | 'routerTag'>, true>)
105105
: {}
106106
)
107107
</script>

packages/bootstrap-vue-next/src/components/BBreadcrumb/BBreadcrumbItem.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ const computedLinkProps = computed(() =>
100100
underlineOpacity: true,
101101
underlineOpacityHover: true,
102102
icon: true,
103-
} as Record<keyof Omit<BLinkProps, 'event' | 'routerTag'>, true>)
103+
} satisfies Record<keyof Omit<BLinkProps, 'event' | 'routerTag'>, true>)
104104
: {}
105105
)
106106

0 commit comments

Comments
 (0)