1
- import Vue from '../../utils/vue'
2
1
import { mergeData } from 'vue-functional-data-merge'
3
- import prefixPropName from '../../utils/prefix-prop-name'
4
- import unPrefixPropName from '../../utils/unprefix-prop-name'
2
+ import Vue from '../../utils/vue'
5
3
import copyProps from '../../utils/copy-props'
6
4
import pluckProps from '../../utils/pluck-props'
5
+ import prefixPropName from '../../utils/prefix-prop-name'
6
+ import unPrefixPropName from '../../utils/unprefix-prop-name'
7
+ import { htmlOrText } from '../../utils/html'
7
8
import { hasNormalizedSlot , normalizeSlot } from '../../utils/normalize-slot'
8
9
import cardMixin from '../../mixins/card'
9
10
import { BCardBody , props as bodyProps } from './card-body'
@@ -36,49 +37,68 @@ export const BCard = /*#__PURE__*/ Vue.extend({
36
37
functional : true ,
37
38
props,
38
39
render ( h , { props, data, slots, scopedSlots } ) {
39
- const $slots = slots ( )
40
- // Vue < 2.6.x may return undefined for scopedSlots
40
+ const {
41
+ imgLeft,
42
+ imgRight,
43
+ imgStart,
44
+ imgEnd,
45
+ header,
46
+ headerHtml,
47
+ footer,
48
+ footerHtml,
49
+ align,
50
+ textVariant,
51
+ bgVariant,
52
+ borderVariant
53
+ } = props
41
54
const $scopedSlots = scopedSlots || { }
55
+ const $slots = slots ( )
56
+ const slotScope = { }
42
57
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
-
58
+ let $imgFirst = h ( )
59
+ let $imgLast = h ( )
50
60
if ( props . imgSrc ) {
51
- const img = h ( BCardImg , {
61
+ const $ img = h ( BCardImg , {
52
62
props : pluckProps ( cardImgProps , props , unPrefixPropName . bind ( null , 'img' ) )
53
63
} )
64
+
54
65
if ( props . imgBottom ) {
55
- imgLast = img
66
+ $ imgLast = $ img
56
67
} else {
57
- imgFirst = img
68
+ $ imgFirst = $ img
58
69
}
59
70
}
60
71
61
- if ( props . header || props . headerHtml || hasNormalizedSlot ( 'header' , $scopedSlots , $slots ) ) {
62
- header = h (
72
+ let $header = h ( )
73
+ const hasHeaderSlot = hasNormalizedSlot ( 'header' , $scopedSlots , $slots )
74
+ if ( hasHeaderSlot || header || headerHtml ) {
75
+ $header = h (
63
76
BCardHeader ,
64
- { props : pluckProps ( headerProps , props ) } ,
65
- normalizeSlot ( 'header' , { } , $scopedSlots , $slots )
77
+ {
78
+ props : pluckProps ( headerProps , props ) ,
79
+ domProps : hasHeaderSlot ? { } : htmlOrText ( headerHtml , header )
80
+ } ,
81
+ normalizeSlot ( 'header' , slotScope , $scopedSlots , $slots )
66
82
)
67
83
}
68
84
69
- content = normalizeSlot ( 'default' , { } , $scopedSlots , $slots ) || [ ]
85
+ let $content = normalizeSlot ( 'default' , slotScope , $scopedSlots , $slots )
86
+
87
+ // Wrap content in <card-body> when `noBody` prop set
70
88
if ( ! props . noBody ) {
71
- // Wrap content in card-body
72
- content = [ h ( BCardBody , { props : pluckProps ( bodyProps , props ) } , [ ...content ] ) ]
89
+ $content = h ( BCardBody , { props : pluckProps ( bodyProps , props ) } , $content )
73
90
}
74
91
75
- if ( props . footer || props . footerHtml || hasNormalizedSlot ( 'footer' , $scopedSlots , $slots ) ) {
76
- footer = h (
92
+ let $footer = h ( )
93
+ const hasFooterSlot = hasNormalizedSlot ( 'footer' , $scopedSlots , $slots )
94
+ if ( hasFooterSlot || footer || footerHtml ) {
95
+ $footer = h (
77
96
BCardFooter ,
78
97
{
79
- props : pluckProps ( footerProps , props )
98
+ props : pluckProps ( footerProps , props ) ,
99
+ domProps : hasHeaderSlot ? { } : htmlOrText ( footerHtml , footer )
80
100
} ,
81
- normalizeSlot ( 'footer' , { } , $scopedSlots , $slots )
101
+ normalizeSlot ( 'footer' , slotScope , $scopedSlots , $slots )
82
102
)
83
103
}
84
104
@@ -87,16 +107,15 @@ export const BCard = /*#__PURE__*/ Vue.extend({
87
107
mergeData ( data , {
88
108
staticClass : 'card' ,
89
109
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
110
+ 'flex-row' : imgLeft || imgStart ,
111
+ 'flex-row-reverse' : ( imgRight || imgEnd ) && ! ( imgLeft || imgStart ) ,
112
+ [ `text-${ align } ` ] : align ,
113
+ [ `bg-${ bgVariant } ` ] : bgVariant ,
114
+ [ `border-${ borderVariant } ` ] : borderVariant ,
115
+ [ `text-${ textVariant } ` ] : textVariant
97
116
}
98
117
} ) ,
99
- [ imgFirst , header , ... content , footer , imgLast ]
118
+ [ $ imgFirst, $ header, $ content, $ footer, $ imgLast]
100
119
)
101
120
}
102
121
} )
0 commit comments