8000 fix: properly handle HTML props render order (closes #5363) (#5365) · bootstrap-vue/bootstrap-vue@844ecda · GitHub
[go: up one dir, main page]

Skip to content

Commit 844ecda

Browse files
fix: properly handle HTML props render order (closes #5363) (#5365)
* fix(jumbatron): fix html props and ensure correct render order * Update html.js * Update visible.js * Update dropdown.js * Update modal.js * Update modal.spec.js * Update carousel-slide.js * Update card.js * Update carousel-slide.js * Update jumbotron.js * Update card-footer.js * Update card-header.js * Update input-group.js * Update progress-bar.js * Update mixin-caption.js * Update mixin-empty.js * Update mixin-thead.js * Unify prop utils * Update props.js * Merge remote-tracking branch 'origin/dev' into fix-jumbatron-html-props * Update dropdown.spec.js * Update dropdown.spec.js * Update dropdown.spec.js * Update dropdown.spec.js * Update modal.spec.js * Update modal.spec.js * Update breadcrumb-link.js * Update card-footer.js * Update card-header.js * Update form-select-option-group.js * Update form-datalist.js * Update test.yml * Merge remote-tracking branch 'origin/dev' into fix-jumbatron-html-props * Update toast.js * Update form-select.js * Update form-radio-check-group.js * Update mixin-thead.js Co-authored-by: Troy Morehouse <troymore@nbnet.nb.ca>
1 parent a5df131 commit 844ecda

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+776
-595
lines changed

.github/workflows/test.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,4 +207,3 @@ jobs:
207207
run: yarn run bundlewatch
208208
env:
209209
BUNDLEWATCH_GITHUB_TOKEN: "${{ secrets.BUNDLEWATCH_GITHUB_TOKEN }}"
210-
CI_BRANCH_BASE: "${{ github.base_ref }}"

src/components/avatar/avatar.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import Vue from '../../utils/vue'
2-
import pluckProps from '../../utils/pluck-props'
32
import { getComponentConfig } from '../../utils/config'
43
import { isNumber, isString, isUndefinedOrNull } from '../../utils/inspect'
54
import { toFloat } from '../../utils/number'
65
import { omit } from '../../utils/object'
6+
import { pluckProps } from '../../utils/props'
77
import { isLink } from '../../utils/router'
88
import { BButton } from '../button/button'
99
import { BLink, props as BLinkProps } from '../link/link'

src/components/badge/badge.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import Vue from '../../utils/vue'
2-
import pluckProps from '../../utils/pluck-props'
31
import { mergeData } from 'vue-functional-data-merge'
2+
import Vue from '../../utils/vue'
43
import { getComponentConfig } from '../../utils/config'
54
import { omit } from '../../utils/object'
5+
import { pluckProps } from '../../utils/props'
66
import { isLink } from '../../utils/router'
77
import { BLink, props as BLinkProps } from '../link/link'
88

src/components/breadcrumb/breadcrumb-link.js

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import { mergeData } from 'vue-functional-data-merge'
22
import Vue from '../../utils/vue'
3-
import pluckProps from '../../utils/pluck-props'
43
import { htmlOrText } from '../../utils/html'
54
import { omit } from '../../utils/object'
5+
import { pluckProps } from '../../utils/props'
66
import { BLink, props as BLinkProps } from '../link/link'
77

8+
// --- Props ---
9+
810
export const props = {
911
text: {
1012
type: String,
@@ -21,17 +23,19 @@ export const props = {
2123
...omit(BLinkProps, ['event', 'routerTag'])
2224
}
2325

26+
// --- Main component ---
2427
// @vue/component
2528
export const BBreadcrumbLink = /*#__PURE__*/ Vue.extend({
2629
name: 'BBreadcrumbLink',
2730
functional: true,
2831
props,
2932
render(h, { props: suppliedProps, data, children }) {
30-
const tag = suppliedProps.active ? 'span' : BLink
33+
const { active } = suppliedProps
34+
const tag = active ? 'span' : BLink
3135

32-
const componentData = { props: pluckProps(props, suppliedProps) }
33-
if (suppliedProps.active) {
34-
componentData.attrs = { 'aria-current': suppliedProps.ariaCurrent }
36+
const componentData = {
37+
attrs: { 'aria-current': active ? suppliedProps.ariaCurrent : null },
38+
props: pluckProps(props, suppliedProps)
3539
}
3640

3741
if (!children) {

src/components/button/button.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import Vue from '../../utils/vue'
21
import { mergeData } from 'vue-functional-data-merge'
2+
import Vue from '../../utils/vue'
33
import KeyCodes from '../../utils/key-codes'
4-
import pluckProps from '../../utils/pluck-props'
54
import { concat } from '../../utils/array'
65
import { getComponentConfig } from '../../utils/config'
76
import { addClass, isTag, removeClass } from '../../utils/dom'
87
import { isBoolean, isEvent, isFunction } from '../../utils/inspect'
98
import { omit } from '../../utils/object'
9+
import { pluckProps } from '../../utils/props'
1010
import { isLink as isLinkStrict } from '../../utils/router'
1111
import { BLink, props as BLinkProps } from '../link/link'
1212

src/components/card/card-body.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
import Vue from '../../utils/vue'
21
import { mergeData } from 'vue-functional-data-merge'
3-
import prefixPropName from '../../utils/prefix-prop-name'
4-
import copyProps from '../../utils/copy-props'
5-
import pluckProps from '../../utils/pluck-props'
2+
import Vue from '../../utils/vue'
3+
import { copyProps, pluckProps, prefixPropName } from '../../utils/props'
64
import cardMixin from '../../mixins/card'
75
import { BCardTitle, props as titleProps } from './card-title'
86
import { BCardSubTitle, props as subTitleProps } from './card-sub-title'

src/components/card/card-footer.js

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import Vue from '../../utils/vue'
21
import { mergeData } from 'vue-functional-data-merge'
3-
4-
import prefixPropName from '../../utils/prefix-prop-name'
5-
import copyProps from '../../utils/copy-props'
2+
import Vue from '../../utils/vue'
63
import { htmlOrText } from '../../utils/html'
4+
import { copyProps, prefixPropName } from '../../utils/props'
75
import cardMixin from '../../mixins/card'
86

7+
// --- Props ---
8+
99
export const props = {
1010
...copyProps(cardMixin.props, prefixPropName.bind(null, 'footer')),
1111
footer: {
@@ -22,26 +22,30 @@ export const props = {
2222
}
2323
}
2424

25+
// --- Main component ---
2526
// @vue/component
2627
export const BCardFooter = /*#__PURE__*/ Vue.extend({
2728
name: 'BCardFooter',
2829
functional: true,
2930
props,
3031
render(h, { props, data, children }) {
32+
const { footerBgVariant, footerBorderVariant, footerTextVariant } = props
33+
3134
return h(
3235
props.footerTag,
3336
mergeData(data, {
3437
staticClass: 'card-footer',
3538
class: [
3639
props.footerClass,
3740
{
38-
[`bg-${props.footerBgVariant}`]: props.footerBgVariant,
39-
[`border-${props.footerBorderVariant}`]: props.footerBorderVariant,
40-
[`text-${props.footerTextVariant}`]: props.footerTextVariant
41+
[`bg-${footerBgVariant}`]: footerBgVariant,
42+
[`border-${footerBorderVariant}`]: footerBorderVariant,
43+
[`text-${footerTextVariant}`]: footerTextVariant
4144
}
42-
]
45+
],
46+
domProps: children ? {} : htmlOrText(props.footerHtml, props.footer)
4347
}),
44-
children || [h('div', { domProps: htmlOrText(props.footerHtml, props.footer) })]
48+
children
4549
)
4650
}
4751
})

src/components/card/card-header.js

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
import Vue from '../../utils/vue'
21
import { mergeData } from 'vue-functional-data-merge'
3-
import prefixPropName from '../../utils/prefix-prop-name'
4-
import copyProps from '../../utils/copy-props'
2+
import Vue from '../../utils/vue'
53
import { htmlOrText } from '../../utils/html'
4+
import { copyProps, prefixPropName } from '../../utils/props'
65
import cardMixin from '../../mixins/card'
76

7+
// --- Props ---
8+
89
export const props = {
910
...copyProps(cardMixin.props, prefixPropName.bind(null, 'header')),
1011
header: {
@@ -21,26 +22,30 @@ export const props = {
2122
}
2223
}
2324

25+
// --- Main component ---
2426
// @vue/component
2527
export const BCardHeader = /*#__PURE__*/ Vue.extend({
2628
name: 'BCardHeader',
2729
functional: true,
2830
props,
2931
render(h, { props, data, children }) {
32+
const { headerBgVariant, headerBorderVariant, headerTextVariant } = props
33+
3034
return h(
3135
props.headerTag,
3236
mergeData(data, {
3337
staticClass: 'card-header',
3438
class: [
3539
props.headerClass,
3640
{
37-
[`bg-${props.headerBgVariant}`]: props.headerBgVariant,
38-
[`border-${props.headerBorderVariant}`]: props.headerBorderVariant,
39-
[`text-${props.headerTextVariant}`]: props.headerTextVariant
41+
[`bg-${headerBgVariant}`]: headerBgVariant,
42+
[`border-${headerBorderVariant}`]: headerBorderVariant,
43+
[`text-${headerTextVariant}`]: headerTextVariant
4044
}
41-
]
45+
],
46+
domProps: children ? {} : htmlOrText(props.headerHtml, props.header)
4247
}),
43-
children || [h('div', { domProps: htmlOrText(props.headerHtml, props.header) })]
48+
children
4449
)
4550
}
4651
})

src/components/card/card.js

Lines changed: 53 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
import Vue from '../../utils/vue'
21
import { mergeData } from 'vue-functional-data-merge'
3-
import prefixPropName from '../../utils/prefix-prop-name'
4-
import unPrefixPropName from '../../utils/unprefix-prop-name'
5-
import copyProps from '../../utils/copy-props'
6-
import pluckProps from '../../utils/pluck-props'
2+
import Vue from '../../utils/vue'
3+
import { htmlOrText } from '../../utils/html'
74
import { hasNormalizedSlot, normalizeSlot } from '../../utils/normalize-slot'
5+
import { copyProps, pluckProps, prefixPropName, unprefixPropName } from '../../utils/props'
86
import cardMixin from '../../mixins/card'
97
import { BCardBody, props as bodyProps } from './card-body'
108
import { BCardHeader, props as headerProps } from './card-header'
@@ -36,49 +34,68 @@ export const BCard = /*#__PURE__*/ Vue.extend({
3634
functional: true,
3735
props,
3836
render(h, { props, data, slots, scopedSlots }) {
39-
const $slots = slots()
40-
// Vue < 2.6.x may return undefined for scopedSlots
37+
const {
38+
imgLeft,
39+
imgRight,
40+
imgStart,
41+
imgEnd,
42+
header,
43+
headerHtml,
44+
footer,
45+
footerHtml,
46+
align,
47+
textVariant,
48+
bgVariant,
49+
borderVariant
50+
} = props
4151
const $scopedSlots = scopedSlots || {}
52+
const $slots = slots()
53+
const slotScope = {}
4254

43-
// Create placeholder elements for each section
44-
let imgFirst = h()
45-
let header = h()
46-
let content = h()
47-
let footer = h()
48-
let imgLast = h()
49-
55+
let $imgFirst = h()
56+
let $imgLast = h()
5057
if (props.imgSrc) {
51-
const img = h(BCardImg, {
52-
props: pluckProps(cardImgProps, props, unPrefixPropName.bind(null, 'img'))
58+
const $img = h(BCardImg, {
59+
props: pluckProps(cardImgProps, props, unprefixPropName.bind(null, 'img'))
5360
})
61+
5462
if (props.imgBottom) {
55-
imgLast = img
63+
$imgLast = $img
5664
} else {
57-
imgFirst = img
65+
$imgFirst = $img
5866
}
5967
}
6068

61-
if (props.header || props.headerHtml || hasNormalizedSlot('header', $scopedSlots, $slots)) {
62-
header = h(
69+
let $header = h()
70+
const hasHeaderSlot = hasNormalizedSlot('header', $scopedSlots, $slots)
71+
if (hasHeaderSlot || header || headerHtml) {
72+
$header = h(
6373
BCardHeader,
64-
{ props: pluckProps(headerProps, props) },
65-
normalizeSlot('header', {}, $scopedSlots, $slots)
74+
{
75+
props: pluckProps(headerProps, props),
76+
domProps: hasHeaderSlot ? {} : htmlOrText(headerHtml, header)
77+
},
78+
normalizeSlot('header', slotScope, $scopedSlots, $slots)
6679
)
6780
}
6881

69-
content = normalizeSlot('default', {}, $scopedSlots, $slots) || []
82+
let $content = normalizeSlot('default', slotScope, $scopedSlots, $slots)
83+
84+
// Wrap content in <card-body> when `noBody` prop set
7085
if (!props.noBody) {
71-
// Wrap content in card-body
72-
content = [h(BCardBody, { props: pluckProps(bodyProps, props) }, [...content])]
86+
$content = h(BCardBody, { props: pluckProps(bodyProps, props) }, $content)
7387
}
7488

75-
if (props.footer || props.footerHtml || hasNormalizedSlot('footer', $scopedSlots, $slots)) {
76-
footer = h(
89+
let $footer = h()
90+
const hasFooterSlot = hasNormalizedSlot('footer', $scopedSlots, $slots)
91+
if (hasFooterSlot || footer || footerHtml) {
92+
$footer = h(
7793
BCardFooter,
7894
{
79-
props: pluckProps(footerProps, props)
95+
props: pluckProps(footerProps, props),
96+
domProps: hasHeaderSlot ? {} : htmlOrText(footerHtml, footer)
8097
},
81-
normalizeSlot('footer', {}, $scopedSlots, $slots)
98+
normalizeSlot('footer', slotScope, $scopedSlots, $slots)
8299
)
83100
}
84101

@@ -87,16 +104,15 @@ export const BCard = /*#__PURE__*/ Vue.extend({
87104
mergeData(data, {
88105
staticClass: 'card',
89106
class: {
90-
'flex-row': props.imgLeft || props.imgStart,
91-
'flex-row-reverse':
92-
(props.imgRight || props.imgEnd) && !(props.imgLeft || props.imgStart),
93-
[`text-${props.align}`]: props.align,
94-
[`bg-${props.bgVariant}`]: props.bgVariant,
95-
[`border-${props.borderVariant}`]: props.borderVariant,
96-
[`text-${props.textVariant}`]: props.textVariant
107+
'flex-row': imgLeft || imgStart,
108+
'flex-row-reverse': (imgRight || imgEnd) && !(imgLeft || imgStart),
109+
[`text-${align}`]: align,
110+
[`bg-${bgVariant}`]: bgVariant,
111+
[`border-${borderVariant}`]: borderVariant,
112+
[`text-${textVariant}`]: textVariant
97113
}
98114
}),
99-
[imgFirst, header, ...content, footer, imgLast]
115+
[$imgFirst, $header, $content, $footer, $imgLast]
100116
)
101117
}
102118
})

0 commit comments

Comments
 (0)
0