From 9b3ef62ed111578a6a32789f0b448853bf536f88 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Tue, 12 May 2020 17:48:45 -0300 Subject: [PATCH 01/40] feat(b-link): add support 3rd party router links such as Gridsome's `` --- src/components/link/link.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/components/link/link.js b/src/components/link/link.js index 05b622ee40e..f517d7cd7d8 100644 --- a/src/components/link/link.js +++ b/src/components/link/link.js @@ -82,6 +82,15 @@ export const propsFactory = () => ({ noPrefetch: { type: Boolean, default: false + }, + // To support 3rd party router links based on router link + // i.e. set to `g-link` for Gridsome + // Default is to auto choose `` vs `` + // As Grdisome doesn't provide a mechanism to auto detect + // And has caveats such as not supporting FQDN URLs or hash only URLs + routerComponentName: { + type: String + // default: undefined } }) From 322fdc502af256ca37a686b17cf5b74af2407b4a Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Tue, 12 May 2020 18:06:04 -0300 Subject: [PATCH 02/40] Update link.js --- src/components/link/link.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/link/link.js b/src/components/link/link.js index f517d7cd7d8..2ddb5976863 100644 --- a/src/components/link/link.js +++ b/src/components/link/link.js @@ -106,7 +106,11 @@ export const BLink = /*#__PURE__*/ Vue.extend({ computed: { computedTag() { // We don't pass `this` as the first arg as we need reactivity of the props - return computeTag({ to: this.to, disabled: this.disabled }, this) + return computeTag({ + to: this.to, + disabled: this.disabled, + routerComponentName: this.routerComponentName + }, this) }, isRouterLink() { return isRouterLink(this.computedTag) From c4c3b0aa93580041eff824dda558f063a4132313 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Tue, 12 May 2020 18:30:15 -0300 Subject: [PATCH 03/40] Update router.js --- src/utils/router.js | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/utils/router.js b/src/utils/router.js index dc7be512648..f77ce62cdfc 100644 --- a/src/utils/router.js +++ b/src/utils/router.js @@ -89,12 +89,26 @@ export const parseQuery = query => { export const isRouterLink = tag => toString(tag).toLowerCase() !== ANCHOR_TAG -export const computeTag = ({ to, disabled } = {}, thisOrParent) => { - return thisOrParent.$router && to && !disabled - ? thisOrParent.$nuxt +export const computeTag = ({ to, disabled, routerComponentName } = {}, thisOrParent) => { + const hasRouter = thisOrParent.$router + if (!hasRouter || (hasRouter && disabled) || !to) { + return ANCHOR_TAG + } + + // Possible To Do: + // Check registered components for existance of user supplied + // router link component name. We would need to check PascalCase, + // kebab-case, and camelCase versions of name: + // const name = routerComponentName + // const names = [name, PascalCase(name), KebabCase(name), CamelCase(name)] + // exists = names.some(name => !!thisOrParent.$options.components[name]) + // And may want to cache the result for performance + // Or: we just let the render fail if the component is not registered + return routerComponentName + ? routerComponentName + : thisOrParent.$nuxt ? 'nuxt-link' : 'router-link' - : ANCHOR_TAG } export const computeRel = ({ target, rel } = {}) => { From 58aad606502d6f62d2aa2b955f891a984f462e8c Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Tue, 12 May 2020 18:42:06 -0300 Subject: [PATCH 04/40] Update link.js --- src/components/link/link.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/link/link.js b/src/components/link/link.js index 2ddb5976863..55962b470f8 100644 --- a/src/components/link/link.js +++ b/src/components/link/link.js @@ -83,9 +83,9 @@ export const propsFactory = () => ({ type: Boolean, default: false }, - // To support 3rd party router links based on router link + // To support 3rd party router links based on `` // i.e. set to `g-link` for Gridsome - // Default is to auto choose `` vs `` + // Default is to auto choose betwen `` and `` // As Grdisome doesn't provide a mechanism to auto detect // And has caveats such as not supporting FQDN URLs or hash only URLs routerComponentName: { From e2e7153b730260f247afef83a8e0ae7e86d050bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20M=C3=BCller?= Date: Wed, 13 May 2020 00:02:14 +0200 Subject: [PATCH 05/40] Update router.js --- src/utils/router.js | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/utils/router.js b/src/utils/router.js index f77ce62cdfc..99a56f4edb7 100644 --- a/src/utils/router.js +++ b/src/utils/router.js @@ -95,20 +95,15 @@ export const computeTag = ({ to, disabled, routerComponentName } = {}, thisOrPar return ANCHOR_TAG } - // Possible To Do: - // Check registered components for existance of user supplied - // router link component name. We would need to check PascalCase, - // kebab-case, and camelCase versions of name: + // TODO: + // Check registered components for existence of user supplied router link component name + // We would need to check PascalCase, kebab-case, and camelCase versions of name: // const name = routerComponentName // const names = [name, PascalCase(name), KebabCase(name), CamelCase(name)] // exists = names.some(name => !!thisOrParent.$options.components[name]) - // And may want to cache the result for performance - // Or: we just let the render fail if the component is not registered - return routerComponentName - ? routerComponentName - : thisOrParent.$nuxt - ? 'nuxt-link' - : 'router-link' + // And may want to cache the result for performance or we just let the render fail + // if the component is not registered + return routerComponentName || thisOrParent.$nuxt ? 'nuxt-link' : 'router-link' } export const computeRel = ({ target, rel } = {}) => { From cb4ac22994d66fb7a32239e880da4100624c321b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20M=C3=BCller?= Date: Wed, 13 May 2020 00:02:19 +0200 Subject: [PATCH 06/40] Update link.js --- src/components/link/link.js | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/components/link/link.js b/src/components/link/link.js index 55962b470f8..3c83b619e96 100644 --- a/src/components/link/link.js +++ b/src/components/link/link.js @@ -83,11 +83,10 @@ export const propsFactory = () => ({ type: Boolean, default: false }, - // To support 3rd party router links based on `` - // i.e. set to `g-link` for Gridsome - // Default is to auto choose betwen `` and `` - // As Grdisome doesn't provide a mechanism to auto detect - // And has caveats such as not supporting FQDN URLs or hash only URLs + // To support 3rd party router links based on `` (i.e. `g-link` for Gridsome) + // Default is to auto choose between `` and `` + // Gridsome doesn't provide a mechanism to auto detect and has caveats + // such as not supporting FQDN URLs or hash only URLs routerComponentName: { type: String // default: undefined @@ -106,11 +105,8 @@ export const BLink = /*#__PURE__*/ Vue.extend({ computed: { computedTag() { // We don't pass `this` as the first arg as we need reactivity of the props - return computeTag({ - to: this.to, - disabled: this.disabled, - routerComponentName: this.routerComponentName - }, this) + const { to, disabled, routerComponentName } = this + return computeTag({ to, disabled, routerComponentName }, this) }, isRouterLink() { return isRouterLink(this.computedTag) From 9f5c8a9807718b32f3e0860774b1ff54b5ba9348 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Tue, 12 May 2020 21:12:16 -0300 Subject: [PATCH 07/40] Update link.spec.js --- src/components/link/link.spec.js | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/components/link/link.spec.js b/src/components/link/link.spec.js index 3a8830a6d8c..598d91a385d 100644 --- a/src/components/link/link.spec.js +++ b/src/components/link/link.spec.js @@ -332,9 +332,23 @@ describe('b-link', () => { ] }) + // Fake Gridsome `` component + const GLink = { + name: 'GLink', + props: { + to: { + type: [String, Object], + default: '' + } + }, + render(h) { + return h('router-link', { props: this.$props }, [this.$slots.default]) + } + } + const App = localVue.extend({ router, - components: { BLink }, + components: { BLink, GLink }, render(h) { return h('main', [ // router-link @@ -345,6 +359,8 @@ describe('b-link', () => { h('b-link', { props: { to: { path: '/b' } } }, ['to-path-b']), // regular link h('b-link', { props: { href: '/b' } }, ['href-a']), + // g-link + h('b-link', { props: { routerComponentName: 'g-link', to: '/a' } }, ['glink-a']), h('router-view') ]) } @@ -358,7 +374,7 @@ describe('b-link', () => { expect(wrapper.vm).toBeDefined() expect(wrapper.element.tagName).toBe('MAIN') - expect(wrapper.findAll('a').length).toBe(4) + expect(wrapper.findAll('a').length).toBe(5) const $links = wrapper.findAll('a') @@ -380,6 +396,11 @@ describe('b-link', () => { expect($links.at(3).vm.$options.name).toBe('BLink') expect($links.at(3).vm.$children.length).toBe(0) + expect($links.at(4).vm).toBeDefined() + expect($links.at(4).vm.$options.name).toBe('BLink') + expect($links.at(4).vm.$children.length).toBe(1) + expect($links.at(4).vm.$children[0].$options.name).toBe('GLink') + wrapper.destroy() }) }) From 0ff9889b14b49c1ce02ef39b7c91f134792d4604 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Tue, 12 May 2020 21:43:02 -0300 Subject: [PATCH 08/40] Update link.spec.js --- src/components/link/link.spec.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/link/link.spec.js b/src/components/link/link.spec.js index 598d91a385d..9b556c81a52 100644 --- a/src/components/link/link.spec.js +++ b/src/components/link/link.spec.js @@ -1,5 +1,5 @@ import VueRouter from 'vue-router' -import { mount, createLocalVue as CreateLocalVue } from '@vue/test-utils' +import { mount, createLocalVue } from '@vue/test-utils' import { createContainer } from '../../../tests/utils' import { BLink } from './link' @@ -200,7 +200,7 @@ describe('b-link', () => { }) describe('click handling', () => { - const localVue = new CreateLocalVue() + const localVue = createLocalVue() it('should invoke click handler bound by Vue when clicked on', async () => { let called = 0 @@ -320,7 +320,7 @@ describe('b-link', () => { describe('router-link support', () => { it('works', async () => { - const localVue = new CreateLocalVue() + const localVue = createLocalVue() localVue.use(VueRouter) const router = new VueRouter({ @@ -342,7 +342,7 @@ describe('b-link', () => { } }, render(h) { - return h('router-link', { props: this.$props }, [this.$slots.default]) + return h('RouterLink', { props: this.$props }, [this.$slots.default]) } } From c531102f9ff4e7469f14aaddf627d98420494746 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Tue, 12 May 2020 21:50:23 -0300 Subject: [PATCH 09/40] Update link.spec.js --- src/components/link/link.spec.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/link/link.spec.js b/src/components/link/link.spec.js index 9b556c81a52..67dba05201b 100644 --- a/src/components/link/link.spec.js +++ b/src/components/link/link.spec.js @@ -342,7 +342,9 @@ describe('b-link', () => { } }, render(h) { - return h('RouterLink', { props: this.$props }, [this.$slots.default]) + // We just us a simple A tag to render teh fake g-link + // and assume `to` is a string + return h('a', { attrs: { href: this.to } }, [this.$slots.default]) } } From 43b9dd378336e22583ce237607b00e04a467abd8 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Tue, 12 May 2020 22:05:24 -0300 Subject: [PATCH 10/40] Update link.spec.js --- src/components/link/link.spec.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/link/link.spec.js b/src/components/link/link.spec.js index 67dba05201b..7a8086f973b 100644 --- a/src/components/link/link.spec.js +++ b/src/components/link/link.spec.js @@ -362,7 +362,7 @@ describe('b-link', () => { // regular link h('b-link', { props: { href: '/b' } }, ['href-a']), // g-link - h('b-link', { props: { routerComponentName: 'g-link', to: '/a' } }, ['glink-a']), + // h('b-link', { props: { routerComponentName: 'g-link', to: '/a' } }, ['glink-a']), h('router-view') ]) } @@ -376,7 +376,7 @@ describe('b-link', () => { expect(wrapper.vm).toBeDefined() expect(wrapper.element.tagName).toBe('MAIN') - expect(wrapper.findAll('a').length).toBe(5) + expect(wrapper.findAll('a').length).toBe(4) const $links = wrapper.findAll('a') @@ -398,10 +398,10 @@ describe('b-link', () => { expect($links.at(3).vm.$options.name).toBe('BLink') expect($links.at(3).vm.$children.length).toBe(0) - expect($links.at(4).vm).toBeDefined() - expect($links.at(4).vm.$options.name).toBe('BLink') - expect($links.at(4).vm.$children.length).toBe(1) - expect($links.at(4).vm.$children[0].$options.name).toBe('GLink') + // expect($links.at(4).vm).toBeDefined() + // expect($links.at(4).vm.$options.name).toBe('BLink') + // expect($links.at(4).vm.$children.length).toBe(1) + // expect($links.at(4).vm.$children[0].$options.name).toBe('GLink') wrapper.destroy() }) From 50490afba21dc56229332ec0718ba9abeefa769c Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Tue, 12 May 2020 22:07:44 -0300 Subject: [PATCH 11/40] Update router.js --- src/utils/router.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/router.js b/src/utils/router.js index 99a56f4edb7..bbb3e4fb2f8 100644 --- a/src/utils/router.js +++ b/src/utils/router.js @@ -103,7 +103,7 @@ export const computeTag = ({ to, disabled, routerComponentName } = {}, thisOrPar // exists = names.some(name => !!thisOrParent.$options.components[name]) // And may want to cache the result for performance or we just let the render fail // if the component is not registered - return routerComponentName || thisOrParent.$nuxt ? 'nuxt-link' : 'router-link' + return routerComponentName || (thisOrParent.$nuxt ? 'nuxt-link' : 'router-link') } export const computeRel = ({ target, rel } = {}) => { From 9b35bc2f8b6dc6193c43f0e9cd50eea3ed7e853a Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Tue, 12 May 2020 22:13:25 -0300 Subject: [PATCH 12/40] Update router.js --- src/utils/router.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/router.js b/src/utils/router.js index bbb3e4fb2f8..c9ca7be5683 100644 --- a/src/utils/router.js +++ b/src/utils/router.js @@ -91,7 +91,7 @@ export const isRouterLink = tag => toString(tag).toLowerCase() !== ANCHOR_TAG export const computeTag = ({ to, disabled, routerComponentName } = {}, thisOrParent) => { const hasRouter = thisOrParent.$router - if (!hasRouter || (hasRouter && disabled) || !to) { + if (!hasRouter || (hasRouter && disabled) || (hasRouter && !to)) { return ANCHOR_TAG } From afa4358c209c25656c1869278c3c8379a5e9ab05 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Tue, 12 May 2020 22:14:39 -0300 Subject: [PATCH 13/40] Update link.spec.js --- src/components/link/link.spec.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/components/link/link.spec.js b/src/components/link/link.spec.js index 7a8086f973b..ba22f0eeff4 100644 --- a/src/components/link/link.spec.js +++ b/src/components/link/link.spec.js @@ -342,8 +342,8 @@ describe('b-link', () => { } }, render(h) { - // We just us a simple A tag to render teh fake g-link - // and assume `to` is a string + // We just us a simple A tag to render the + // fake `` and assume `to` is a string return h('a', { attrs: { href: this.to } }, [this.$slots.default]) } } @@ -362,7 +362,7 @@ describe('b-link', () => { // regular link h('b-link', { props: { href: '/b' } }, ['href-a']), // g-link - // h('b-link', { props: { routerComponentName: 'g-link', to: '/a' } }, ['glink-a']), + h('b-link', { props: { routerComponentName: 'g-link', to: '/a' } }, ['glink-a']), h('router-view') ]) } @@ -376,7 +376,7 @@ describe('b-link', () => { expect(wrapper.vm).toBeDefined() expect(wrapper.element.tagName).toBe('MAIN') - expect(wrapper.findAll('a').length).toBe(4) + expect(wrapper.findAll('a').length).toBe(5) const $links = wrapper.findAll('a') @@ -398,10 +398,10 @@ describe('b-link', () => { expect($links.at(3).vm.$options.name).toBe('BLink') expect($links.at(3).vm.$children.length).toBe(0) - // expect($links.at(4).vm).toBeDefined() - // expect($links.at(4).vm.$options.name).toBe('BLink') - // expect($links.at(4).vm.$children.length).toBe(1) - // expect($links.at(4).vm.$children[0].$options.name).toBe('GLink') + expect($links.at(4).vm).toBeDefined() + expect($links.at(4).vm.$options.name).toBe('BLink') + expect($links.at(4).vm.$children.length).toBe(1) + expect($links.at(4).vm.$children[0].$options.name).toBe('GLink') wrapper.destroy() }) From af4461d6575079ab5a5f37e01e17bfccfb3b5965 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Tue, 12 May 2020 22:20:25 -0300 Subject: [PATCH 14/40] Update link.spec.js --- src/components/link/link.spec.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/link/link.spec.js b/src/components/link/link.spec.js index ba22f0eeff4..0bbe294ff81 100644 --- a/src/components/link/link.spec.js +++ b/src/components/link/link.spec.js @@ -348,9 +348,11 @@ describe('b-link', () => { } } + localVue.component('GLink', GLink) + const App = localVue.extend({ router, - components: { BLink, GLink }, + components: { BLink }, render(h) { return h('main', [ // router-link From c9d8d4c6310ad4feaceb22407bb8a6f332d0d163 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Tue, 12 May 2020 22:28:51 -0300 Subject: [PATCH 15/40] Update common-props.json --- docs/common-props.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/common-props.json b/docs/common-props.json index 78ccfa2bf83..5be9fc1ab3c 100644 --- a/docs/common-props.json +++ b/docs/common-props.json @@ -236,5 +236,9 @@ }, "noPrefetch": { "description": "nuxt-link prop: To improve the responsiveness of your Nuxt.js applications, when the link will be displayed within the viewport, Nuxt.js will automatically prefetch the code splitted page. Setting 'no-prefetch' will disabled this feature for the specific link" + }, + "routerComponentName": { + "description": "BootstrapVue auto detects between `` and ``. In cases where you want to use a 3rd party link component based on ``, set this prop to the component name. e.g. set it to 'g-link' if you are using Gridsome", + "version": "2.15.0" } } From 08a5a5a984df032a4854d1f7a45ad711fe9c8c5d Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Tue, 12 May 2020 22:29:45 -0300 Subject: [PATCH 16/40] Update link.js --- src/components/link/link.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/components/link/link.js b/src/components/link/link.js index b32d1ad1edc..909c077db27 100644 --- a/src/components/link/link.js +++ b/src/components/link/link.js @@ -43,6 +43,14 @@ export const routerLinkProps = { routerTag: { type: String, default: 'a' + }, + // To support 3rd party router links based on `` (i.e. `g-link` for Gridsome) + // Default is to auto choose between `` and `` + // Gridsome doesn't provide a mechanism to auto detect and has caveats + // such as not supporting FQDN URLs or hash only URLs + routerComponentName: { + type: String + // default: undefined } } @@ -61,14 +69,6 @@ export const nuxtLinkProps = { noPrefetch: { type: Boolean, default: false - }, - // To support 3rd party router links based on `` (i.e. `g-link` for Gridsome) - // Default is to auto choose between `` and `` - // Gridsome doesn't provide a mechanism to auto detect and has caveats - // such as not supporting FQDN URLs or hash only URLs - routerComponentName: { - type: String - // default: undefined } } From ff65504ea0fd66fde984983ab83876d50337a45d Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Tue, 12 May 2020 22:31:58 -0300 Subject: [PATCH 17/40] Update link.js --- src/components/link/link.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/components/link/link.js b/src/components/link/link.js index 909c077db27..f7c08a2875a 100644 --- a/src/components/link/link.js +++ b/src/components/link/link.js @@ -43,14 +43,6 @@ export const routerLinkProps = { routerTag: { type: String, default: 'a' - }, - // To support 3rd party router links based on `` (i.e. `g-link` for Gridsome) - // Default is to auto choose between `` and `` - // Gridsome doesn't provide a mechanism to auto detect and has caveats - // such as not supporting FQDN URLs or hash only URLs - routerComponentName: { - type: String - // default: undefined } } @@ -95,7 +87,15 @@ export const props = { default: false }, ...routerLinkProps, - ...nuxtLinkProps + ...nuxtLinkProps, + // To support 3rd party router links based on `` (i.e. `g-link` for Gridsome) + // Default is to auto choose between `` and `` + // Gridsome doesn't provide a mechanism to auto detect and has caveats + // such as not supporting FQDN URLs or hash only URLs + routerComponentName: { + type: String + // default: undefined + } } // --- Main component --- From 1fa2a5804079062c2c0b98de7a43e693a02cfe4e Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Tue, 12 May 2020 22:38:41 -0300 Subject: [PATCH 18/40] Update common-props.json --- docs/common-props.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/common-props.json b/docs/common-props.json index 5be9fc1ab3c..424cca40626 100644 --- a/docs/common-props.json +++ b/docs/common-props.json @@ -238,7 +238,7 @@ "description": "nuxt-link prop: To improve the responsiveness of your Nuxt.js applications, when the link will be displayed within the viewport, Nuxt.js will automatically prefetch the code splitted page. Setting 'no-prefetch' will disabled this feature for the specific link" }, "routerComponentName": { - "description": "BootstrapVue auto detects between `` and ``. In cases where you want to use a 3rd party link component based on ``, set this prop to the component name. e.g. set it to 'g-link' if you are using Gridsome", + "description": "BootstrapVue auto detects between `` and ``. In cases where you want to use a 3rd party link component based on ``, set this prop to the component name. e.g. set it to 'g-link' if you are using Gridsome (note only `` specific props are passed to the component)", "version": "2.15.0" } } From 98195ecc6ba5cce799871dede520f542df1201d8 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Tue, 12 May 2020 23:11:32 -0300 Subject: [PATCH 19/40] Update README.md --- .../markdown/reference/router-links/README.md | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/docs/markdown/reference/router-links/README.md b/docs/markdown/reference/router-links/README.md index 796cd12ee93..f3d75f4a7f8 100644 --- a/docs/markdown/reference/router-links/README.md +++ b/docs/markdown/reference/router-links/README.md @@ -10,7 +10,8 @@ In the following sections, we are using the `` component to render router links. `` is the building block of most of BootstrapVue's _actionable_ components. You could use any other component that supports link generation such as [``](/docs/components/link), -[``](/docs/components/button), [``](/docs/components/breadcrumb), +[``](/docs/components/button), [``](/docs/components/avatar), +[``](/docs/components/breadcrumb), [``](/docs/components/list-group), [``](/docs/components/nav), [``](/docs/components/dropdown), and [``](/docs/components/pagination-nav). Note that not all props are available on @@ -203,3 +204,28 @@ disabled this feature for the specific link. **Note:** If you have prefetching disabled in your `nuxt.config.js` configuration (`router: { prefetchLinks: false }`), or are using a version of Nuxt.js `< 2.4.0`, then this prop will have no effect. + +## Third-party router link support + +v2.15.0+ + +BootstrapVue auto detects using `` and `` link components. Some 3rd party +frameworks also provide customized versions of ``, such as +[Gridsome's `` component](https://gridsome.org/docs/linking/). BootstrapVue can support +these third party `` compatible components via the use of the `router-component-name` +prop. All `vue-router` props (excluding `` specific props) will be passed to the +specified router link component. + +Note that the 3rd arty component will only be used when the `to` prop is set. + +### `router-component-name` + +- type: `string` +- default: `undefined` +- availability: BootstrapVue 2.15.0+ + +Set this prop to the name of the `` compatible component, e.g. `'g-link''` for +[Gridsome](https://gridsome.org/). + +If left at the default, BootstrapVue will automatically select `` or ``. + From 2aa3ef01ad2c2e6468bd983d30fb13c3e406dc2e Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Tue, 12 May 2020 23:11:49 -0300 Subject: [PATCH 20/40] Update README.md --- docs/markdown/reference/router-links/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/markdown/reference/router-links/README.md b/docs/markdown/reference/router-links/README.md index f3d75f4a7f8..22f0a242086 100644 --- a/docs/markdown/reference/router-links/README.md +++ b/docs/markdown/reference/router-links/README.md @@ -224,7 +224,7 @@ Note that the 3rd arty component will only be used when the `to` prop is set. - default: `undefined` - availability: BootstrapVue 2.15.0+ -Set this prop to the name of the `` compatible component, e.g. `'g-link''` for +Set this prop to the name of the `` compatible component, e.g. `'g-link'` for [Gridsome](https://gridsome.org/). If left at the default, BootstrapVue will automatically select `` or ``. From f42d245b72a7e48b1cb48b83e8e6ec3acf454179 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Tue, 12 May 2020 23:26:26 -0300 Subject: [PATCH 21/40] Update avatar.js --- src/components/avatar/avatar.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/avatar/avatar.js b/src/components/avatar/avatar.js index 6501aede88e..59ba31a34f4 100644 --- a/src/components/avatar/avatar.js +++ b/src/components/avatar/avatar.js @@ -38,7 +38,8 @@ const linkProps = pluckProps( 'exact', 'exactActiveClass', 'prefetch', - 'noPrefetch' + 'noPrefetch', + 'routerComponentName' ], BLinkProps ) From 510d408572bc8d2705068eea8873d854173cc675 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Tue, 12 May 2020 23:27:52 -0300 Subject: [PATCH 22/40] Update common-props.json --- docs/common-props.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/common-props.json b/docs/common-props.json index 424cca40626..f07023684c0 100644 --- a/docs/common-props.json +++ b/docs/common-props.json @@ -238,7 +238,7 @@ "description": "nuxt-link prop: To improve the responsiveness of your Nuxt.js applications, when the link will be displayed within the viewport, Nuxt.js will automatically prefetch the code splitted page. Setting 'no-prefetch' will disabled this feature for the specific link" }, "routerComponentName": { - "description": "BootstrapVue auto detects between `` and ``. In cases where you want to use a 3rd party link component based on ``, set this prop to the component name. e.g. set it to 'g-link' if you are using Gridsome (note only `` specific props are passed to the component)", + "description": "b-link prop: BootstrapVue auto detects between `` and ``. In cases where you want to use a 3rd party link component based on ``, set this prop to the component name. e.g. set it to 'g-link' if you are using Gridsome (note only `` specific props are passed to the component)", "version": "2.15.0" } } From 68f5d4c5dc05038ff76935b036d36914d72b4b42 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 13 May 2020 03:49:11 -0300 Subject: [PATCH 23/40] Update README.md --- src/components/link/README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/components/link/README.md b/src/components/link/README.md index 2a381eabbd8..5aabd1b95b4 100644 --- a/src/components/link/README.md +++ b/src/components/link/README.md @@ -26,6 +26,17 @@ If your app is running under [Nuxt.js](https://nuxtjs.org), the ``. The `` component supports all the same features as `` (as it is a wrapper component for ``) and more. +### Third party rounter links + +BootstrapVue auto detects using `` and `` link components. Some 3rd party +frameworks also provide customized versions of ``, such as +[Gridsome's `` component](https://gridsome.org/docs/linking/). `` can support these +third party `` compatible components via the use of the `router-component-name` prop. +All vue-router props (excluding `` specific props) will be passed to the specified router +link component. + +Note that the 3rd party component will only be used when the `to` prop is set. + ## Links with `href="#"` Typically `` will cause the document to scroll to the top of page when clicked. From c60e77a31000b254670a3e1a9ee6e0bc86a9f458 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 13 May 2020 03:49:53 -0300 Subject: [PATCH 24/40] Update README.md --- docs/markdown/reference/router-links/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/markdown/reference/router-links/README.md b/docs/markdown/reference/router-links/README.md index 22f0a242086..35640e5b129 100644 --- a/docs/markdown/reference/router-links/README.md +++ b/docs/markdown/reference/router-links/README.md @@ -216,7 +216,7 @@ these third party `` compatible components via the use of the `rout prop. All `vue-router` props (excluding `` specific props) will be passed to the specified router link component. -Note that the 3rd arty component will only be used when the `to` prop is set. +Note that the 3rd party component will only be used when the `to` prop is set. ### `router-component-name` From 0d85c331e5c006ba2000424a3e2b81501181cf76 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 13 May 2020 03:55:40 -0300 Subject: [PATCH 25/40] Update README.md --- docs/markdown/reference/router-links/README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/markdown/reference/router-links/README.md b/docs/markdown/reference/router-links/README.md index 35640e5b129..dc024435f2e 100644 --- a/docs/markdown/reference/router-links/README.md +++ b/docs/markdown/reference/router-links/README.md @@ -216,7 +216,12 @@ these third party `` compatible components via the use of the `rout prop. All `vue-router` props (excluding `` specific props) will be passed to the specified router link component. -Note that the 3rd party component will only be used when the `to` prop is set. +**Notes:** + +- The 3rd party component will only be used when the `to` prop is set. +- Not all 3rd party components support all props supported by ``, nor do not support + fully qualified domain name URLs, nor hash only URLs. Refer to the 3rd party component + documentation for details. ### `router-component-name` From 793982eb38c4368729809cced293f5b10ea9deac Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 13 May 2020 04:07:46 -0300 Subject: [PATCH 26/40] Update common-props.json --- docs/common-props.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/common-props.json b/docs/common-props.json index f07023684c0..d30dd0187d9 100644 --- a/docs/common-props.json +++ b/docs/common-props.json @@ -197,14 +197,14 @@ "active": { "description": "When set to 'true', places the component in the active state with active styling" }, + "href": { + "description": "b-link prop: Denotes the target URL of the link for standard a links" + }, "rel": { - "description": "Sets the 'rel' attribute on the rendered link" + "description": "b-link prop: Sets the 'rel' attribute on the rendered link" }, "target": { - "description": "Sets the 'target' attribute on the rendered link" - }, - "href": { - "description": "Denotes the target URL of the link for standard a links" + "description": "b-link prop: Sets the 'target' attribute on the rendered link" }, "to": { "description": "router-link prop: Denotes the target route of the link. When clicked, the value of the to prop will be passed to router.push() internally, so the value can be either a string or a Location descriptor object" From 19dc655a041f68b69e3ae2318e2905b5bd5bda97 Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 13 May 2020 04:10:49 -0300 Subject: [PATCH 27/40] Update package.json --- src/components/link/package.json | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/components/link/package.json b/src/components/link/package.json index 4671251ef80..b5400530c42 100644 --- a/src/components/link/package.json +++ b/src/components/link/package.json @@ -7,7 +7,20 @@ "components": [ { "component": "BLink", - "props": [], + "props": [ + { + "prop": "href", + "description": "Denotes the target URL of the link for standard a links" + }, + { + "prop": "rel", + "description": "Sets the 'rel' attribute on the rendered link" + }, + { + "prop": "target", + "description": "Sets the 'target' attribute on the rendered link" + } + ], "events": [ { "event": "click", From 2bae70ed028bd9c62e3935f851388317f6ad35b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20M=C3=BCller?= Date: Wed, 13 May 2020 09:28:31 +0200 Subject: [PATCH 28/40] Update common-props.json --- docs/common-props.json | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/common-props.json b/docs/common-props.json index d30dd0187d9..2ea9d8d6cd5 100644 --- a/docs/common-props.json +++ b/docs/common-props.json @@ -198,47 +198,47 @@ "description": "When set to 'true', places the component in the active state with active styling" }, "href": { - "description": "b-link prop: Denotes the target URL of the link for standard a links" + "description": " prop: Denotes the target URL of the link for standard a links" }, "rel": { - "description": "b-link prop: Sets the 'rel' attribute on the rendered link" + "description": " prop: Sets the 'rel' attribute on the rendered link" }, "target": { - "description": "b-link prop: Sets the 'target' attribute on the rendered link" + "description": " prop: Sets the 'target' attribute on the rendered link" }, "to": { - "description": "router-link prop: Denotes the target route of the link. When clicked, the value of the to prop will be passed to router.push() internally, so the value can be either a string or a Location descriptor object" + "description": " prop: Denotes the target route of the link. When clicked, the value of the to prop will be passed to router.push() internally, so the value can be either a string or a Location descriptor object" }, "replace": { - "description": "router-link prop: Setting the replace prop will call 'router.replace()' instead of 'router.push()' when clicked, so the navigation will not leave a history record" + "description": " prop: Setting the replace prop will call 'router.replace()' instead of 'router.push()' when clicked, so the navigation will not leave a history record" }, "append": { - "description": "router-link prop: Setting append prop always appends the relative path to the current path" + "description": " prop: Setting append prop always appends the relative path to the current path" }, "exact": { - "description": "router-link prop: The default active class matching behavior is inclusive match. Setting this prop forces the mode to exactly match the route" + "description": " prop: The default active class matching behavior is inclusive match. Setting this prop forces the mode to exactly match the route" }, "activeClass": { - "description": "router-link prop: Configure the active CSS class applied when the link is active. Typically you will want to set this to class name 'active'" + "description": " prop: Configure the active CSS class applied when the link is active. Typically you will want to set this to class name 'active'" }, "exactActiveClass": { - "description": "router-link prop: Configure the active CSS class applied when the link is active with exact match. Typically you will want to set this to class name 'active'" + "description": " prop: Configure the active CSS class applied when the link is active with exact match. Typically you will want to set this to class name 'active'" }, "routerTag": { - "description": "router-link prop: Specify which tag to render, and it will still listen to click events for navigation. 'router-tag' translates to the tag prop on the final rendered router-link. Typically you should use the default value" + "description": " prop: Specify which tag to render, and it will still listen to click events for navigation. 'router-tag' translates to the tag prop on the final rendered router-link. Typically you should use the default value" }, "event": { - "description": "router-link prop: Specify the event that triggers the link. In most cases you should leave this as the default" + "description": " prop: Specify the event that triggers the link. In most cases you should leave this as the default" }, "prefetch": { - "description": "nuxt-link prop: To improve the responsiveness of your Nuxt.js applications, when the link will be displayed within the viewport, Nuxt.js will automatically prefetch the code splitted page. Setting 'prefetch' to 'true' or 'false' will overwrite the default value of 'router.prefetchLinks'", + "description": " prop: To improve the responsiveness of your Nuxt.js applications, when the link will be displayed within the viewport, Nuxt.js will automatically prefetch the code splitted page. Setting 'prefetch' to 'true' or 'false' will overwrite the default value of 'router.prefetchLinks'", "version": "2.15.0" }, "noPrefetch": { - "description": "nuxt-link prop: To improve the responsiveness of your Nuxt.js applications, when the link will be displayed within the viewport, Nuxt.js will automatically prefetch the code splitted page. Setting 'no-prefetch' will disabled this feature for the specific link" + "description": " prop: To improve the responsiveness of your Nuxt.js applications, when the link will be displayed within the viewport, Nuxt.js will automatically prefetch the code splitted page. Setting 'no-prefetch' will disabled this feature for the specific link" }, "routerComponentName": { - "description": "b-link prop: BootstrapVue auto detects between `` and ``. In cases where you want to use a 3rd party link component based on ``, set this prop to the component name. e.g. set it to 'g-link' if you are using Gridsome (note only `` specific props are passed to the component)", + "description": " prop: BootstrapVue auto detects between `` and ``. In cases where you want to use a 3rd party link component based on ``, set this prop to the component name. e.g. set it to 'g-link' if you are using Gridsome (note only `` specific props are passed to the component)", "version": "2.15.0" } } From 0c188235164d48b5f61cfb0ace6adfb385ede36c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20M=C3=BCller?= Date: Wed, 13 May 2020 09:28:37 +0200 Subject: [PATCH 29/40] Update package.json --- src/components/dropdown/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/dropdown/package.json b/src/components/dropdown/package.json index a049dd7a235..4c541db9974 100644 --- a/src/components/dropdown/package.json +++ b/src/components/dropdown/package.json @@ -97,7 +97,7 @@ }, { "prop": "splitTo", - "description": "router-link prop: Denotes the target route of the split button. When clicked, the value of the to prop will be passed to router.push() internally, so the value can be either a string or a Location descriptor object" + "description": " prop: Denotes the target route of the split button. When clicked, the value of the to prop will be passed to router.push() internally, so the value can be either a string or a Location descriptor object" }, { "prop": "splitVariant", From 60eb95e15aef07a4fa418a245e5a20e3e517ca45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20M=C3=BCller?= Date: Wed, 13 May 2020 09:31:41 +0200 Subject: [PATCH 30/40] Update README.md --- docs/markdown/reference/router-links/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/markdown/reference/router-links/README.md b/docs/markdown/reference/router-links/README.md index dc024435f2e..88e7a91de36 100644 --- a/docs/markdown/reference/router-links/README.md +++ b/docs/markdown/reference/router-links/README.md @@ -233,4 +233,3 @@ Set this prop to the name of the `` compatible component, e.g. `'g- [Gridsome](https://gridsome.org/). If left at the default, BootstrapVue will automatically select `` or ``. - From eee65198284928737f36361d59aaef38ea56a9f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20M=C3=BCller?= Date: Wed, 13 May 2020 09:37:22 +0200 Subject: [PATCH 31/40] Update avatar.js --- src/components/avatar/avatar.js | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/src/components/avatar/avatar.js b/src/components/avatar/avatar.js index 59ba31a34f4..2e6e6b739c1 100644 --- a/src/components/avatar/avatar.js +++ b/src/components/avatar/avatar.js @@ -3,6 +3,7 @@ import pluckProps from '../../utils/pluck-props' import { getComponentConfig } from '../../utils/config' import { isNumber, isString, isUndefinedOrNull } from '../../utils/inspect' import { toFloat } from '../../utils/number' +import { omit } from '../../utils/object' import { BButton } from '../button/button' import { BLink, props as BLinkProps } from '../link/link' import { BIcon } from '../../icons/icon' @@ -25,24 +26,7 @@ const DEFAULT_SIZES = { } // --- Props --- -const linkProps = pluckProps( - [ - 'href', - 'rel', - 'target', - 'disabled', - 'to', - 'append', - 'replace', - 'activeClass', - 'exact', - 'exactActiveClass', - 'prefetch', - 'noPrefetch', - 'routerComponentName' - ], - BLinkProps -) +const linkProps = omit(BLinkProps, ['active', 'event', 'routerTag']) const props = { src: { From 7998397a1147e6832d958a3cd815e5e634933dc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20M=C3=BCller?= Date: Wed, 13 May 2020 09:38:11 +0200 Subject: [PATCH 32/40] Update README.md --- src/components/link/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/link/README.md b/src/components/link/README.md index 5aabd1b95b4..d51b06f6f71 100644 --- a/src/components/link/README.md +++ b/src/components/link/README.md @@ -32,8 +32,8 @@ BootstrapVue auto detects using `` and `` link component frameworks also provide customized versions of ``, such as [Gridsome's `` component](https://gridsome.org/docs/linking/). `` can support these third party `` compatible components via the use of the `router-component-name` prop. -All vue-router props (excluding `` specific props) will be passed to the specified router -link component. +All `vue-router` props (excluding `` specific props) will be passed to the specified +router link component. Note that the 3rd party component will only be used when the `to` prop is set. From 9f55cc7ab4587e52fa15c191f7b2cbb30620e552 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20M=C3=BCller?= Date: Wed, 13 May 2020 09:50:39 +0200 Subject: [PATCH 33/40] Merge remote-tracking branch 'origin/dev' into blink-gridsome From fdd6a8a43431eb698fda755fcefd551bd39ce682 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20M=C3=BCller?= Date: Wed, 13 May 2020 09:56:42 +0200 Subject: [PATCH 34/40] Make sure to always omit ``'s `event` prop for other components --- src/components/badge/badge.js | 4 ++-- src/components/breadcrumb/breadcrumb-link.js | 5 +++-- src/components/button/button.js | 4 ++-- src/components/dropdown/dropdown-item.js | 4 ++-- src/components/list-group/list-group-item.js | 4 ++-- src/components/nav/nav-item.js | 4 ++-- src/components/navbar/navbar-brand.js | 4 ++-- .../pagination-nav/pagination-nav.js | 18 +++++++++++++++--- 8 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/components/badge/badge.js b/src/components/badge/badge.js index ab2399e16fe..355f43e9edb 100644 --- a/src/components/badge/badge.js +++ b/src/components/badge/badge.js @@ -2,12 +2,12 @@ import Vue from '../../utils/vue' import pluckProps from '../../utils/pluck-props' import { mergeData } from 'vue-functional-data-merge' import { getComponentConfig } from '../../utils/config' -import { clone } from '../../utils/object' +import { omit } from '../../utils/object' import { BLink, props as BLinkProps } from '../link/link' const NAME = 'BBadge' -const linkProps = clone(BLinkProps) +const linkProps = omit(BLinkProps, ['event']) delete linkProps.href.default delete linkProps.to.default diff --git a/src/components/breadcrumb/breadcrumb-link.js b/src/components/breadcrumb/breadcrumb-link.js index a2cc8b1961e..752978f7850 100644 --- a/src/components/breadcrumb/breadcrumb-link.js +++ b/src/components/breadcrumb/breadcrumb-link.js @@ -1,7 +1,8 @@ -import Vue from '../../utils/vue' import { mergeData } from 'vue-functional-data-merge' +import Vue from '../../utils/vue' import pluckProps from '../../utils/pluck-props' import { htmlOrText } from '../../utils/html' +import { omit } from '../../utils/object' import { BLink, props as BLinkProps } from '../link/link' export const props = { @@ -17,7 +18,7 @@ export const props = { type: String, default: 'location' }, - ...BLinkProps + ...omit(BLinkProps, ['event']) } // @vue/component diff --git a/src/components/button/button.js b/src/components/button/button.js index e7c9382c556..1f41c65761e 100644 --- a/src/components/button/button.js +++ b/src/components/button/button.js @@ -6,7 +6,7 @@ import { concat } from '../../utils/array' import { getComponentConfig } from '../../utils/config' import { addClass, removeClass } from '../../utils/dom' import { isBoolean, isEvent, isFunction } from '../../utils/inspect' -import { clone } from '../../utils/object' +import { omit } from '../../utils/object' import { toString } from '../../utils/string' import { BLink, props as BLinkProps } from '../link/link' @@ -16,7 +16,7 @@ const NAME = 'BButton' // --- Props --- -const linkProps = clone(BLinkProps) +const linkProps = omit(BLinkProps, ['event']) delete linkProps.href.default delete linkProps.to.default diff --git a/src/components/dropdown/dropdown-item.js b/src/components/dropdown/dropdown-item.js index 01af4fe1478..f60b561d6b0 100644 --- a/src/components/dropdown/dropdown-item.js +++ b/src/components/dropdown/dropdown-item.js @@ -1,11 +1,11 @@ import Vue from '../../utils/vue' import { requestAF } from '../../utils/dom' -import { clone } from '../../utils/object' +import { omit } from '../../utils/object' import attrsMixin from '../../mixins/attrs' import normalizeSlotMixin from '../../mixins/normalize-slot' import { BLink, props as BLinkProps } from '../link/link' -export const props = clone(BLinkProps) +export const props = omit(BLinkProps, ['event']) // @vue/component export const BDropdownItem = /*#__PURE__*/ Vue.extend({ diff --git a/src/components/list-group/list-group-item.js b/src/components/list-group/list-group-item.js index f41bf0c3e77..59d611c0fdd 100644 --- a/src/components/list-group/list-group-item.js +++ b/src/components/list-group/list-group-item.js @@ -3,7 +3,7 @@ import Vue from '../../utils/vue' import pluckProps from '../../utils/pluck-props' import { arrayIncludes } from '../../utils/array' import { getComponentConfig } from '../../utils/config' -import { clone } from '../../utils/object' +import { omit } from '../../utils/object' import { BLink, props as BLinkProps } from '../link/link' // --- Constants --- @@ -14,7 +14,7 @@ const actionTags = ['a', 'router-link', 'button', 'b-link'] // --- Props --- -const linkProps = clone(BLinkProps) +const linkProps = omit(BLinkProps, ['event']) delete linkProps.href.default delete linkProps.to.default diff --git a/src/components/nav/nav-item.js b/src/components/nav/nav-item.js index a5796140354..a4315a25d88 100644 --- a/src/components/nav/nav-item.js +++ b/src/components/nav/nav-item.js @@ -1,11 +1,11 @@ import { mergeData } from 'vue-functional-data-merge' import Vue from '../../utils/vue' -import { clone } from '../../utils/object' +import { omit } from '../../utils/object' import { BLink, props as BLinkProps } from '../link/link' // --- Props --- -export const props = clone(BLinkProps) +export const props = omit(BLinkProps, ['event']) // --- Main component --- // @vue/component diff --git a/src/components/navbar/navbar-brand.js b/src/components/navbar/navbar-brand.js index 144f8e2e0ef..e919180035a 100644 --- a/src/components/navbar/navbar-brand.js +++ b/src/components/navbar/navbar-brand.js @@ -1,10 +1,10 @@ import { mergeData } from 'vue-functional-data-merge' import Vue from '../../utils/vue' import pluckProps from '../../utils/pluck-props' -import { clone } from '../../utils/object' +import { omit } from '../../utils/object' import { BLink, props as BLinkProps } from '../link/link' -const linkProps = clone(BLinkProps) +const linkProps = omit(BLinkProps, ['event']) linkProps.href.default = undefined linkProps.to.default = undefined diff --git a/src/components/pagination-nav/pagination-nav.js b/src/components/pagination-nav/pagination-nav.js index b3b2678f8b9..c5fc3153d42 100644 --- a/src/components/pagination-nav/pagination-nav.js +++ b/src/components/pagination-nav/pagination-nav.js @@ -13,10 +13,16 @@ import { warn } from '../../utils/warn' import paginationMixin from '../../mixins/pagination' import { props as BLinkProps } from '../link/link' +// --- Constants --- + const NAME = 'BPaginationNav' -// Sanitize the provided number of pages (converting to a number) -export const sanitizeNumberOfPages = value => mathMax(toInteger(value, 0), 1) +// --- Props --- + +const linkProps = pluckProps( + ['activeClass', 'exact', 'exactActiveClass', 'prefetch', 'noPrefetch', 'routerComponentName'], + BLinkProps +) const props = { size: { @@ -61,9 +67,15 @@ const props = { type: Boolean, default: false }, - ...pluckProps(['activeClass', 'exact', 'exactActiveClass', 'prefetch', 'noPrefetch'], BLinkProps) + ...linkProps } +// --- Utility methods --- + +// Sanitize the provided number of pages (converting to a number) +export const sanitizeNumberOfPages = value => mathMax(toInteger(value, 0), 1) + +// --- Main component --- // The render function is brought in via the pagination mixin // @vue/component export const BPaginationNav = /*#__PURE__*/ Vue.extend({ From a918a7c369d4b69155cc38568d8ccc4050964c05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20M=C3=BCller?= Date: Wed, 13 May 2020 09:59:33 +0200 Subject: [PATCH 35/40] Add `routerComponentName` to global config --- src/components/link/link.js | 9 +++++++-- src/utils/config-defaults.js | 3 +++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/components/link/link.js b/src/components/link/link.js index f7c08a2875a..0e86918d71d 100644 --- a/src/components/link/link.js +++ b/src/components/link/link.js @@ -1,6 +1,7 @@ import Vue from '../../utils/vue' import pluckProps from '../../utils/pluck-props' import { concat } from '../../utils/array' +import { getComponentConfig } from '../../utils/config' import { attemptBlur, attemptFocus } from '../../utils/dom' import { isBoolean, isEvent, isFunction, isUndefined } from '../../utils/inspect' import { computeHref, computeRel, computeTag, isRouterLink } from '../../utils/router' @@ -8,6 +9,10 @@ import attrsMixin from '../../mixins/attrs' import listenersMixin from '../../mixins/listeners' import normalizeSlotMixin from '../../mixins/normalize-slot' +// --- Constants --- + +const NAME = 'BLink' + // --- Props --- // specific props @@ -93,8 +98,8 @@ export const props = { // Gridsome doesn't provide a mechanism to auto detect and has caveats // such as not supporting FQDN URLs or hash only URLs routerComponentName: { - type: String - // default: undefined + type: String, + default: () => getComponentConfig(NAME, 'routerComponentName') } } diff --git a/src/utils/config-defaults.js b/src/utils/config-defaults.js index 410f382162c..e896f67248c 100644 --- a/src/utils/config-defaults.js +++ b/src/utils/config-defaults.js @@ -183,6 +183,9 @@ export default deepFreeze({ borderVariant: undefined, textVariant: undefined }, + BLink: { + routerComponentName: undefined + }, BListGroupItem: { variant: undefined }, From 505d638010ae91674811cf82923dfdcbf3736f3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20M=C3=BCller?= Date: Wed, 13 May 2020 10:09:11 +0200 Subject: [PATCH 36/40] Update pagination-nav.js --- .../pagination-nav/pagination-nav.js | 33 ++----------------- 1 file changed, 3 insertions(+), 30 deletions(-) diff --git a/src/components/pagination-nav/pagination-nav.js b/src/components/pagination-nav/pagination-nav.js index c5fc3153d42..688f40278e8 100644 --- a/src/components/pagination-nav/pagination-nav.js +++ b/src/components/pagination-nav/pagination-nav.js @@ -7,6 +7,7 @@ import { isBrowser } from '../../utils/env' import { isArray, isUndefined, isFunction, isObject } from '../../utils/inspect' import { mathMax } from '../../utils/math' import { toInteger } from '../../utils/number' +import { omit } from '../../utils/object' import { computeHref, parseQuery } from '../../utils/router' import { toString } from '../../utils/string' import { warn } from '../../utils/warn' @@ -19,10 +20,7 @@ const NAME = 'BPaginationNav' // --- Props --- -const linkProps = pluckProps( - ['activeClass', 'exact', 'exactActiveClass', 'prefetch', 'noPrefetch', 'routerComponentName'], - BLinkProps -) +const linkProps = omit(BLinkProps, ['event']) const props = { size: { @@ -187,38 +185,13 @@ export const BPaginationNav = /*#__PURE__*/ Vue.extend({ return info.link }, linkProps(pageNum) { + const props = pluckProps(linkProps, this.$props) const link = this.makeLink(pageNum) - const { - disabled, - exact, - activeClass, - exactActiveClass, - append, - replace, - prefetch, - noPrefetch - } = this - - const props = { - target: this.target || null, - rel: this.rel || null, - disabled, - // The following props are only used if `BLink` detects router - exact, - activeClass, - exactActiveClass, - append, - replace, - // specific prop - prefetch, - noPrefetch - } if (this.useRouter || isObject(link)) { props.to = link } else { props.href = link } - return props }, resolveLink(to = '') { From 4816e2e1c12681487f42ffc3d168139bfad13d84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20M=C3=BCller?= Date: Wed, 13 May 2020 11:08:24 +0200 Subject: [PATCH 37/40] Update pagination-nav.js --- src/components/pagination-nav/pagination-nav.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/pagination-nav/pagination-nav.js b/src/components/pagination-nav/pagination-nav.js index 688f40278e8..b10047c45be 100644 --- a/src/components/pagination-nav/pagination-nav.js +++ b/src/components/pagination-nav/pagination-nav.js @@ -20,7 +20,7 @@ const NAME = 'BPaginationNav' // --- Props --- -const linkProps = omit(BLinkProps, ['event']) +const linkProps = omit(BLinkProps, ['event', 'routerTag']) const props = { size: { From 421bbcdddd1d5b4e9efe9c44ae80c3e1e19f96bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20M=C3=BCller?= Date: Wed, 13 May 2020 11:10:42 +0200 Subject: [PATCH 38/40] Omit `routerTag` for all other components --- src/components/breadcrumb/breadcrumb-link.js | 2 +- src/components/button/button.js | 2 +- src/components/dropdown/dropdown-item.js | 2 +- src/components/nav/nav-item.js | 2 +- src/components/navbar/navbar-brand.js | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/breadcrumb/breadcrumb-link.js b/src/components/breadcrumb/breadcrumb-link.js index 752978f7850..232d1f99d85 100644 --- a/src/components/breadcrumb/breadcrumb-link.js +++ b/src/components/breadcrumb/breadcrumb-link.js @@ -18,7 +18,7 @@ export const props = { type: String, default: 'location' }, - ...omit(BLinkProps, ['event']) + ...omit(BLinkProps, ['event', 'routerTag']) } // @vue/component diff --git a/src/components/button/button.js b/src/components/button/button.js index 1f41c65761e..707c719b196 100644 --- a/src/components/button/button.js +++ b/src/components/button/button.js @@ -16,7 +16,7 @@ const NAME = 'BButton' // --- Props --- -const linkProps = omit(BLinkProps, ['event']) +const linkProps = omit(BLinkProps, ['event', 'routerTag']) delete linkProps.href.default delete linkProps.to.default diff --git a/src/components/dropdown/dropdown-item.js b/src/components/dropdown/dropdown-item.js index f60b561d6b0..d4c2abacd07 100644 --- a/src/components/dropdown/dropdown-item.js +++ b/src/components/dropdown/dropdown-item.js @@ -5,7 +5,7 @@ import attrsMixin from '../../mixins/attrs' import normalizeSlotMixin from '../../mixins/normalize-slot' import { BLink, props as BLinkProps } from '../link/link' -export const props = omit(BLinkProps, ['event']) +export const props = omit(BLinkProps, ['event', 'routerTag']) // @vue/component export const BDropdownItem = /*#__PURE__*/ Vue.extend({ diff --git a/src/components/nav/nav-item.js b/src/components/nav/nav-item.js index a4315a25d88..28af3ab36da 100644 --- a/src/components/nav/nav-item.js +++ b/src/components/nav/nav-item.js @@ -5,7 +5,7 @@ import { BLink, props as BLinkProps } from '../link/link' // --- Props --- -export const props = omit(BLinkProps, ['event']) +export const props = omit(BLinkProps, ['event', 'routerTag']) // --- Main component --- // @vue/component diff --git a/src/components/navbar/navbar-brand.js b/src/components/navbar/navbar-brand.js index e919180035a..774b1afc0cc 100644 --- a/src/components/navbar/navbar-brand.js +++ b/src/components/navbar/navbar-brand.js @@ -4,7 +4,7 @@ import pluckProps from '../../utils/pluck-props' import { omit } from '../../utils/object' import { BLink, props as BLinkProps } from '../link/link' -const linkProps = omit(BLinkProps, ['event']) +const linkProps = omit(BLinkProps, ['event', 'routerTag']) linkProps.href.default = undefined linkProps.to.default = undefined From 2aa64e165ae1742780c8bb55e8392fdff97ef1ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20M=C3=BCller?= Date: Wed, 13 May 2020 11:31:53 +0200 Subject: [PATCH 39/40] Unify link detection in other components --- src/components/avatar/avatar.js | 13 +++--- src/components/badge/badge.js | 14 +++++-- src/components/button/button.js | 13 +++--- src/components/link/link.js | 2 +- src/components/list-group/list-group-item.js | 42 +++++++++++-------- src/components/navbar/navbar-brand.js | 7 +++- src/components/navbar/navbar.js | 8 +++- .../pagination-nav/pagination-nav.js | 2 +- src/components/table/td.js | 6 ++- src/components/toast/toast.js | 28 ++++++------- src/utils/dom.js | 4 ++ src/utils/router.js | 5 ++- 12 files changed, 86 insertions(+), 58 deletions(-) diff --git a/src/components/avatar/avatar.js b/src/components/avatar/avatar.js index 2e6e6b739c1..d9974a53b6a 100644 --- a/src/components/avatar/avatar.js +++ b/src/components/avatar/avatar.js @@ -4,6 +4,7 @@ import { getComponentConfig } from '../../utils/config' import { isNumber, isString, isUndefinedOrNull } from '../../utils/inspect' import { toFloat } from '../../utils/number' import { omit } from '../../utils/object' +import { isLink } from '../../utils/router' import { BButton } from '../button/button' import { BLink, props as BLinkProps } from '../link/link' import { BIcon } from '../../icons/icon' @@ -193,14 +194,14 @@ export const BAvatar = /*#__PURE__*/ Vue.extend({ fontStyle, marginStyle, computedSize: size, - button: isButton, + button, buttonType: type, badge, badgeVariant, badgeStyle } = this - const isBLink = !isButton && (this.href || this.to) - const tag = isButton ? BButton : isBLink ? BLink : 'span' + const link = !button && isLink(this) + const tag = button ? BButton : link ? BLink : 'span' const alt = this.alt || null const ariaLabel = this.ariaLabel || null @@ -246,7 +247,7 @@ export const BAvatar = /*#__PURE__*/ Vue.extend({ staticClass: CLASS_NAME, class: { // We use badge styles for theme variants when not rendering `BButton` - [`badge-${variant}`]: !isButton && variant, + [`badge-${variant}`]: !button && variant, // Rounding/Square rounded: rounded === true, [`rounded-${rounded}`]: rounded && rounded !== true, @@ -255,8 +256,8 @@ export const BAvatar = /*#__PURE__*/ Vue.extend({ }, style: { width: size, height: size, ...marginStyle }, attrs: { 'aria-label': ariaLabel || null }, - props: isButton ? { variant, disabled, type } : isBLink ? pluckProps(linkProps, this) : {}, - on: isBLink || isButton ? { click: this.onClick } : {} + props: button ? { variant, disabled, type } : link ? pluckProps(linkProps, this) : {}, + on: button || link ? { click: this.onClick } : {} } return h(tag, componentData, [$content, $badge]) diff --git a/src/components/badge/badge.js b/src/components/badge/badge.js index 355f43e9edb..47941d8e2ba 100644 --- a/src/components/badge/badge.js +++ b/src/components/badge/badge.js @@ -3,11 +3,16 @@ import pluckProps from '../../utils/pluck-props' import { mergeData } from 'vue-functional-data-merge' import { getComponentConfig } from '../../utils/config' import { omit } from '../../utils/object' +import { isLink } from '../../utils/router' import { BLink, props as BLinkProps } from '../link/link' +// --- Constants --- + const NAME = 'BBadge' -const linkProps = omit(BLinkProps, ['event']) +// --- Props --- + +const linkProps = omit(BLinkProps, ['event', 'routerTag']) delete linkProps.href.default delete linkProps.to.default @@ -27,14 +32,15 @@ export const props = { ...linkProps } +// --- Main component --- // @vue/component export const BBadge = /*#__PURE__*/ Vue.extend({ name: NAME, functional: true, props, render(h, { props, data, children }) { - const isBLink = props.href || props.to - const tag = isBLink ? BLink : props.tag + const link = isLink(props) + const tag = link ? BLink : props.tag const componentData = { staticClass: 'badge', @@ -46,7 +52,7 @@ export const BBadge = /*#__PURE__*/ Vue.extend({ disabled: props.disabled } ], - props: isBLink ? pluckProps(linkProps, props) : {} + props: link ? pluckProps(linkProps, props) : {} } return h(tag, mergeData(data, componentData), children) diff --git a/src/components/button/button.js b/src/components/button/button.js index 707c719b196..7704e66bfbf 100644 --- a/src/components/button/button.js +++ b/src/components/button/button.js @@ -4,10 +4,10 @@ import KeyCodes from '../../utils/key-codes' import pluckProps from '../../utils/pluck-props' import { concat } from '../../utils/array' import { getComponentConfig } from '../../utils/config' -import { addClass, removeClass } from '../../utils/dom' +import { addClass, isTag, removeClass } from '../../utils/dom' import { isBoolean, isEvent, isFunction } from '../../utils/inspect' import { omit } from '../../utils/object' -import { toString } from '../../utils/string' +import { isLink as isLinkStrict } from '../../utils/router' import { BLink, props as BLinkProps } from '../link/link' // --- Constants --- @@ -65,9 +65,6 @@ export const props = { ...btnProps, ...linkProps } // --- Helper methods --- -// Returns `true` if a tag's name equals `name` -const tagIs = (tag, name) => toString(tag).toLowerCase() === toString(name).toLowerCase() - // Focus handler for toggle buttons // Needs class of 'focus' when focused const handleFocus = evt => { @@ -80,13 +77,13 @@ const handleFocus = evt => { // Is the requested button a link? // If tag prop is set to `a`, we use a to get proper disabled handling -const isLink = props => props.href || props.to || tagIs(props.tag, 'a') +const isLink = props => isLinkStrict(props) || isTag(props.tag, 'a') // Is the button to be a toggle button? const isToggle = props => isBoolean(props.pressed) // Is the button "really" a button? -const isButton = props => !(isLink(props) || (props.tag && !tagIs(props.tag, 'button'))) +const isButton = props => !(isLink(props) || (props.tag && !isTag(props.tag, 'button'))) // Is the requested tag not a button or link? const isNonStandardTag = props => !isLink(props) && !isButton(props) @@ -105,7 +102,7 @@ const computeClass = props => [ ] // Compute the link props to pass to b-link (if required) -const computeLinkProps = props => (isLink(props) ? pluckProps(linkProps, props) : null) +const computeLinkProps = props => (isLink(props) ? pluckProps(linkProps, props) : {}) // Compute the attributes for a button const computeAttrs = (props, data) => { diff --git a/src/components/link/link.js b/src/components/link/link.js index 0e86918d71d..60e5c58036a 100644 --- a/src/components/link/link.js +++ b/src/components/link/link.js @@ -132,7 +132,7 @@ export const BLink = /*#__PURE__*/ Vue.extend({ const prefetch = this.prefetch return this.isRouterLink ? { - ...pluckProps({ ...routerLinkProps, ...nuxtLinkProps }, this.$props), + ...pluckProps({ ...routerLinkProps, ...nuxtLinkProps }, this), // Coerce `prefetch` value `null` to be `undefined` prefetch: isBoolean(prefetch) ? prefetch : undefined, // Pass `router-tag` as `tag` prop diff --git a/src/components/list-group/list-group-item.js b/src/components/list-group/list-group-item.js index 59d611c0fdd..dcfdb6fcae5 100644 --- a/src/components/list-group/list-group-item.js +++ b/src/components/list-group/list-group-item.js @@ -3,7 +3,9 @@ import Vue from '../../utils/vue' import pluckProps from '../../utils/pluck-props' import { arrayIncludes } from '../../utils/array' import { getComponentConfig } from '../../utils/config' +import { isTag } from '../../utils/dom' import { omit } from '../../utils/object' +import { isLink } from '../../utils/router' import { BLink, props as BLinkProps } from '../link/link' // --- Constants --- @@ -14,7 +16,7 @@ const actionTags = ['a', 'router-link', 'button', 'b-link'] // --- Props --- -const linkProps = omit(BLinkProps, ['event']) +const linkProps = omit(BLinkProps, ['event', 'routerTag']) delete linkProps.href.default delete linkProps.to.default @@ -45,13 +47,14 @@ export const BListGroupItem = /*#__PURE__*/ Vue.extend({ functional: true, props, render(h, { props, data, children }) { - const tag = props.button ? 'button' : !props.href && !props.to ? props.tag : BLink - const isAction = Boolean( - props.href || props.to || props.action || props.button || arrayIncludes(actionTags, props.tag) - ) + const { button, variant, active, disabled } = props + const link = isLink(props) + const tag = button ? 'button' : !link ? props.tag : BLink + const action = !!(props.action || link || button || arrayIncludes(actionTags, props.tag)) + const attrs = {} let itemProps = {} - if (tag === 'button') { + if (isTag(tag, 'button')) { if (!data.attrs || !data.attrs.type) { // Add a type for button is one not provided in passed attributes attrs.type = 'button' @@ -63,18 +66,21 @@ export const BListGroupItem = /*#__PURE__*/ Vue.extend({ } else { itemProps = pluckProps(linkProps, props) } - const componentData = { - attrs, - props: itemProps, - staticClass: 'list-group-item', - class: { - [`list-group-item-${props.variant}`]: props.variant, - 'list-group-item-action': isAction, - active: props.active, - disabled: props.disabled - } - } - return h(tag, mergeData(data, componentData), children) + return h( + tag, + mergeData(data, { + attrs, + props: itemProps, + staticClass: 'list-group-item', + class: { + [`list-group-item-${variant}`]: variant, + 'list-group-item-action': action, + active, + disabled + } + }), + children + ) } }) diff --git a/src/components/navbar/navbar-brand.js b/src/components/navbar/navbar-brand.js index 774b1afc0cc..835b8801192 100644 --- a/src/components/navbar/navbar-brand.js +++ b/src/components/navbar/navbar-brand.js @@ -4,18 +4,21 @@ import pluckProps from '../../utils/pluck-props' import { omit } from '../../utils/object' import { BLink, props as BLinkProps } from '../link/link' +// --- Props --- + const linkProps = omit(BLinkProps, ['event', 'routerTag']) linkProps.href.default = undefined linkProps.to.default = undefined export const props = { - ...linkProps, tag: { type: String, default: 'div' - } + }, + ...linkProps } +// --- Main component --- // @vue/component export const BNavbarBrand = /*#__PURE__*/ Vue.extend({ name: 'BNavbarBrand', diff --git a/src/components/navbar/navbar.js b/src/components/navbar/navbar.js index eed8ad22cee..5700e79c064 100644 --- a/src/components/navbar/navbar.js +++ b/src/components/navbar/navbar.js @@ -1,10 +1,15 @@ import Vue from '../../utils/vue' import { getComponentConfig, getBreakpoints } from '../../utils/config' +import { isTag } from '../../utils/dom' import { isString } from '../../utils/inspect' import normalizeSlotMixin from '../../mixins/normalize-slot' +// --- Constants --- + const NAME = 'BNavbar' +// --- Props --- + export const props = { tag: { type: String, @@ -35,6 +40,7 @@ export const props = { } } +// --- Main component --- // @vue/component export const BNavbar = /*#__PURE__*/ Vue.extend({ name: NAME, @@ -73,7 +79,7 @@ export const BNavbar = /*#__PURE__*/ Vue.extend({ this.breakpointClass ], attrs: { - role: this.tag === 'nav' ? null : 'navigation' + role: isTag(this.tag, 'nav') ? null : 'navigation' } }, [this.normalizeSlot('default')] diff --git a/src/components/pagination-nav/pagination-nav.js b/src/components/pagination-nav/pagination-nav.js index b10047c45be..fbcccf45c87 100644 --- a/src/components/pagination-nav/pagination-nav.js +++ b/src/components/pagination-nav/pagination-nav.js @@ -185,7 +185,7 @@ export const BPaginationNav = /*#__PURE__*/ Vue.extend({ return info.link }, linkProps(pageNum) { - const props = pluckProps(linkProps, this.$props) + const props = pluckProps(linkProps, this) const link = this.makeLink(pageNum) if (this.useRouter || isObject(link)) { props.to = link diff --git a/src/components/table/td.js b/src/components/table/td.js index cb6ce671823..0fb91c764dd 100644 --- a/src/components/table/td.js +++ b/src/components/table/td.js @@ -1,4 +1,5 @@ import Vue from '../../utils/vue' +import { isTag } from '../../utils/dom' import { isUndefinedOrNull } from '../../utils/inspect' import { toInteger } from '../../utils/number' import { toString } from '../../utils/string' @@ -6,6 +7,8 @@ import attrsMixin from '../../mixins/attrs' import listenersMixin from '../../mixins/listeners' import normalizeSlotMixin from '../../mixins/normalize-slot' +// --- Utility methods --- + // Parse a rowspan or colspan into a digit (or `null` if < `1` ) const parseSpan = value => { value = toInteger(value, 0) @@ -42,6 +45,7 @@ export const props = { } } +// --- Main component --- // TODO: // In Bootstrap v5, we won't need "sniffing" as table element variants properly inherit // to the child elements, so this can be converted to a functional component @@ -160,7 +164,7 @@ export const BTd = /*#__PURE__*/ Vue.extend({ // Header or footer cells role = 'columnheader' scope = colspan > 0 ? 'colspan' : 'col' - } else if (this.tag === 'th') { + } else if (isTag(this.tag, 'th')) { // th's in tbody role = 'rowheader' scope = rowspan > 0 ? 'rowgroup' : 'row' diff --git a/src/components/toast/toast.js b/src/components/toast/toast.js index f3e40224606..3f62de144e5 100644 --- a/src/components/toast/toast.js +++ b/src/components/toast/toast.js @@ -1,12 +1,15 @@ -import Vue from '../../utils/vue' import { Portal, Wormhole } from 'portal-vue' import BVTransition from '../../utils/bv-transition' +import Vue from '../../utils/vue' +import pluckProps from '../../utils/pluck-props' import { BvEvent } from '../../utils/bv-event.class' import { getComponentConfig } from '../../utils/config' import { requestAF } from '../../utils/dom' import { EVENT_OPTIONS_NO_CAPTURE, eventOnOff } from '../../utils/events' import { mathMax } from '../../utils/math' import { toInteger } from '../../utils/number' +import { pick } from '../../utils/object' +import { isLink } from '../../utils/router' import attrsMixin from '../../mixins/attrs' import idMixin from '../../mixins/id' import listenOnRootMixin from '../../mixins/listen-on-root' @@ -14,7 +17,7 @@ import normalizeSlotMixin from '../../mixins/normalize-slot' import scopedStyleAttrsMixin from '../../mixins/scoped-style-attrs' import { BToaster } from './toaster' import { BButtonClose } from '../button/button-close' -import { BLink } from '../link/link' +import { BLink, props as BLinkProps } from '../link/link' // --- Constants --- @@ -24,6 +27,8 @@ const MIN_DURATION = 1000 // --- Props --- +const linkProps = pick(BLinkProps, ['href', 'to']) + export const props = { id: { // Even though the ID prop is provided by idMixin, we @@ -92,19 +97,12 @@ export const props = { type: [String, Object, Array], default: () => getComponentConfig(NAME, 'bodyClass') }, - href: { - type: String - // default: null - }, - to: { - type: [String, Object] - // default: null - }, static: { // Render the toast in place, rather than in a portal-target type: Boolean, default: false - } + }, + ...linkProps } // @vue/component @@ -385,14 +383,14 @@ export const BToast = /*#__PURE__*/ Vue.extend({ ) } // Toast body - const isLink = this.href || this.to + const link = isLink(this) const $body = h( - isLink ? BLink : 'div', + link ? BLink : 'div', { staticClass: 'toast-body', class: this.bodyClass, - props: isLink ? { to: this.to, href: this.href } : {}, - on: isLink ? { click: this.onLinkClick } : {} + props: link ? pluckProps(linkProps, this) : {}, + on: link ? { click: this.onLinkClick } : {} }, [this.normalizeSlot('default', this.slotScope) || h()] ) diff --git a/src/utils/dom.js b/src/utils/dom.js index 59c6a0e0b42..b1857122606 100644 --- a/src/utils/dom.js +++ b/src/utils/dom.js @@ -2,6 +2,7 @@ import { from as arrayFrom } from './array' import { hasWindowSupport, hasDocumentSupport } from './env' import { isFunction, isNull } from './inspect' import { toFloat } from './number' +import { toString } from './string' // --- Constants --- @@ -74,6 +75,9 @@ export const getActiveElement = (excludes = []) => { return activeElement && !excludes.some(el => el === activeElement) ? activeElement : null } +// Returns `true` if a tag's name equals `name` +export const isTag = (tag, name) => toString(tag).toLowerCase() === toString(name).toLowerCase() + // Determine if an HTML element is the currently active element export const isActiveElement = el => isElement(el) && el === getActiveElement() diff --git a/src/utils/router.js b/src/utils/router.js index c9ca7be5683..521de9fd0bd 100644 --- a/src/utils/router.js +++ b/src/utils/router.js @@ -1,3 +1,4 @@ +import { isTag } from './dom' import { isArray, isNull, isPlainObject, isString, isUndefined } from './inspect' import { keys } from './object' import { toString } from './string' @@ -87,7 +88,9 @@ export const parseQuery = query => { return parsed } -export const isRouterLink = tag => toString(tag).toLowerCase() !== ANCHOR_TAG +export const isLink = props => !!(props.href || props.to) + +export const isRouterLink = tag => !isTag(tag, ANCHOR_TAG) export const computeTag = ({ to, disabled, routerComponentName } = {}, thisOrParent) => { const hasRouter = thisOrParent.$router From 8952df31651b47f1443ba49ce80915460b4996ca Mon Sep 17 00:00:00 2001 From: Troy Morehouse Date: Wed, 13 May 2020 22:45:59 -0300 Subject: [PATCH 40/40] Update common-props.json --- docs/common-props.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/common-props.json b/docs/common-props.json index 2ea9d8d6cd5..25cb814ad55 100644 --- a/docs/common-props.json +++ b/docs/common-props.json @@ -239,6 +239,7 @@ }, "routerComponentName": { "description": " prop: BootstrapVue auto detects between `` and ``. In cases where you want to use a 3rd party link component based on ``, set this prop to the component name. e.g. set it to 'g-link' if you are using Gridsome (note only `` specific props are passed to the component)", - "version": "2.15.0" + "version": "2.15.0", + "settings": true } }