diff --git a/src/components/card/README.md b/src/components/card/README.md index 390b3b4c14e..a3f0f98c7dc 100644 --- a/src/components/card/README.md +++ b/src/components/card/README.md @@ -495,6 +495,63 @@ assistive technologies – such as screen readers. Ensure that information denot either obvious from the content itself (e.g. the visible text), or is included through alternative means, such as additional text hidden with the `.sr-only` class. +## Nav integration + +Integrate [``](/docs/components/nav) into card headers easily. + +**Using the `header` slot**: + +```html +
+ + + Active + Inactive + Disabled + + + + With supporting text below as a natural lead-in to additional content. + + + Go somewhere + +
+ + +``` + +**Using `` sub-component:** + +```html +
+ + + + Active + Inactive + Disabled + + + + + Card Title + + + With supporting text below as a natural lead-in to additional content. + + + Go somewhere + + +
+ + +``` + +For more information on using `` in card headers, refer to the +[Navs documentation](/docs/components/nav). + ## Card groups In addition to styling the content within cards, BootstrapVue includes a `` component diff --git a/src/components/nav/README.md b/src/components/nav/README.md index 94dcb4236f1..55a5e9311f0 100644 --- a/src/components/nav/README.md +++ b/src/components/nav/README.md @@ -170,10 +170,10 @@ Use `` to place dropdown items within your nav. toggle-class="nav-link-custom" right > - one - two + One + Two - three + Three @@ -220,6 +220,96 @@ render the menu contents only when it is shown by setting the `lazy` prop to tru See the [``](/docs/components/tabs) component for creating tabbable panes of local content (not suited for navigation). +## Card integration + +Use a `` in a [``](/docs/components/card) header, by enabling the `card-header` prop +on `` and setting either the `pills` or `tabs` props: + +**Tabs style:** + +```html +
+ + + Active + Inactive + Disabled + + One + Two + Three + + + + + With supporting text below as a natural lead-in to additional content. + + + Go somewhere + +
+ + +``` + +**Pill style:** + +```html +
+ + + Active + Inactive + Disabled + + One + Two + Three + + + + + With supporting text below as a natural lead-in to additional content. + + + Go somewhere + +
+ + +``` + +**Plain style:** + +The `card-header` prop is only needed when you are applying `tabs` or `pills` style. + +```html +
+ + + Active + Inactive + Disabled + + One + Two + Three + + + + + With supporting text below as a natural lead-in to additional content. + + + Go somewhere + +
+ + +``` + +The `card-header` prop has no effect if the `` is `vertical`. + ## Accessibility If you're using `` to provide a navigation bar, be sure to add a `role="navigation"` to the diff --git a/src/components/nav/nav.js b/src/components/nav/nav.js index 28a1cc339ca..68a993087de 100644 --- a/src/components/nav/nav.js +++ b/src/components/nav/nav.js @@ -35,6 +35,11 @@ export const props = { small: { type: Boolean, default: false + }, + cardHeader: { + // Set to true if placing in a card header + type: Boolean, + default: false } } @@ -58,7 +63,9 @@ export const BNav = /*#__PURE__*/ Vue.extend({ staticClass: 'nav', class: { 'nav-tabs': props.tabs, - 'nav-pills': props.pills, + 'nav-pills': props.pills && !props.tabs, + 'card-header-tabs': !props.vertical && props.cardHeader && props.tabs, + 'card-header-pills': !props.vertical && props.cardHeader && props.pills && !props.tabs, 'flex-column': props.vertical, 'nav-fill': !props.vertical && props.fill, 'nav-justified': !props.vertical && props.justified, diff --git a/src/components/nav/nav.spec.js b/src/components/nav/nav.spec.js index 00adb817b9f..284a2ab1523 100644 --- a/src/components/nav/nav.spec.js +++ b/src/components/nav/nav.spec.js @@ -179,4 +179,36 @@ describe('nav', () => { expect(wrapper.classes().length).toBe(2) expect(wrapper.text()).toBe('') }) + + it('applies card-header-tabs class when tabs and card-header props set', async () => { + const wrapper = mount(BNav, { + propsData: { + tabs: true, + cardHeader: true + } + }) + + expect(wrapper.is('ul')).toBe(true) + expect(wrapper.classes()).toContain('nav') + expect(wrapper.classes()).toContain('nav-tabs') + expect(wrapper.classes()).toContain('card-header-tabs') + expect(wrapper.classes().length).toBe(3) + expect(wrapper.text()).toBe('') + }) + + it('applies card-header-pills class when pills and card-header props set', async () => { + const wrapper = mount(BNav, { + propsData: { + pills: true, + cardHeader: true + } + }) + + expect(wrapper.is('ul')).toBe(true) + expect(wrapper.classes()).toContain('nav') + expect(wrapper.classes()).toContain('nav-pills') + expect(wrapper.classes()).toContain('card-header-pills') + expect(wrapper.classes().length).toBe(3) + expect(wrapper.text()).toBe('') + }) }) diff --git a/src/components/tabs/tabs.js b/src/components/tabs/tabs.js index 5ac2cb43586..7569db53c2a 100644 --- a/src/components/tabs/tabs.js +++ b/src/components/tabs/tabs.js @@ -232,17 +232,10 @@ export const BTabs = /*#__PURE__*/ Vue.extend({ // This computed prop is sniffed by the tab child return !this.noFade }, - navStyle() { - return this.pills ? 'pills' : 'tabs' - }, localNavClass() { const classes = [] - if (this.card) { - if (this.vertical) { - classes.push('card-header', 'h-100', 'border-bottom-0', 'rounded-0') - } else { - classes.push(`card-header-${this.navStyle}`) - } + if (this.card && this.vertical) { + classes.push('card-header', 'h-100', 'border-bottom-0', 'rounded-0') } return [...classes, this.navClass] } @@ -640,7 +633,8 @@ export const BTabs = /*#__PURE__*/ Vue.extend({ tabs: !this.noNavStyle && !this.pills, pills: !this.noNavStyle && this.pills, vertical: this.vertical, - small: this.small + small: this.small, + cardHeader: this.card && !this.vertical } }, [this.normalizeSlot('tabs-start') || h(), buttons, this.normalizeSlot('tabs-end') || h()] diff --git a/src/directives/scrollspy/README.md b/src/directives/scrollspy/README.md index 78fae488ebc..8880aa175ac 100644 --- a/src/directives/scrollspy/README.md +++ b/src/directives/scrollspy/README.md @@ -30,7 +30,7 @@ as well.