1- import Vue from '../../utils/vue'
21import { 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'
74import { hasNormalizedSlot , normalizeSlot } from '../../utils/normalize-slot'
5+ import { copyProps , pluckProps , prefixPropName , unprefixPropName } from '../../utils/props'
86import cardMixin from '../../mixins/card'
97import { BCardBody , props as bodyProps } from './card-body'
108import { 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