11import identity from '../../../utils/identity'
22import KeyCodes from '../../../utils/key-codes'
3+ import noop from '../../../utils/noop'
34import startCase from '../../../utils/startcase'
45import { getComponentConfig } from '../../../utils/config'
56import { htmlOrText } from '../../../utils/html'
@@ -62,42 +63,52 @@ export default {
6263 return h ( )
6364 }
6465
66+ const {
67+ isSortable,
68+ isSelectable,
69+ headVariant,
70+ footVariant,
71+ headRowVariant,
72+ footRowVariant
73+ } = this
74+ const hasHeadClickListener = isSortable || this . hasListener ( 'head-clicked' )
75+
6576 // Reference to `selectAllRows` and `clearSelected()`, if table is selectable
66- const selectAllRows = this . isSelectable ? this . selectAllRows : ( ) => { }
67- const clearSelected = this . isSelectable ? this . clearSelected : ( ) => { }
77+ const selectAllRows = isSelectable ? this . selectAllRows : noop
78+ const clearSelected = isSelectable ? this . clearSelected : noop
6879
6980 // Helper function to generate a field <th> cell
7081 const makeCell = ( field , colIndex ) => {
82+ const { label, labelHtml, variant, stickyColumn, key } = field
83+
7184 let ariaLabel = null
7285 if ( ! field . label . trim ( ) && ! field . headerTitle ) {
7386 // In case field's label and title are empty/blank
7487 // We need to add a hint about what the column is about for non-sighted users
7588 /* istanbul ignore next */
7689 ariaLabel = startCase ( field . key )
7790 }
78- const hasHeadClickListener = this . hasListener ( 'head-clicked' ) || this . isSortable
79- const handlers = { }
91+
92+ const on = { }
8093 if ( hasHeadClickListener ) {
81- handlers . click = evt => {
94+ on . click = evt => {
8295 this . headClicked ( evt , field , isFoot )
8396 }
84- handlers . keydown = evt => {
97+ on . keydown = evt => {
8598 const keyCode = evt . keyCode
8699 if ( keyCode === KeyCodes . ENTER || keyCode === KeyCodes . SPACE ) {
87100 this . headClicked ( evt , field , isFoot )
88101 }
89102 }
90103 }
91- const sortAttrs = this . isSortable ? this . sortTheadThAttrs ( field . key , field , isFoot ) : { }
92- const sortClass = this . isSortable ? this . sortTheadThClasses ( field . key , field , isFoot ) : null
93- const sortLabel = this . isSortable ? this . sortTheadThLabel ( field . key , field , isFoot ) : null
104+
105+ const sortAttrs = isSortable ? this . sortTheadThAttrs ( key , field , isFoot ) : { }
106+ const sortClass = isSortable ? this . sortTheadThClasses ( key , field , isFoot ) : null
107+ const sortLabel = isSortable ? this . sortTheadThLabel ( key , field , isFoot ) : null
108+
94109 const data = {
95- key : field . key ,
96110 class : [ this . fieldClasses ( field ) , sortClass ] ,
97- props : {
98- variant : field . variant ,
99- stickyColumn : field . stickyColumn
100- } ,
111+ props : { variant, stickyColumn } ,
101112 style : field . thStyle || { } ,
102113 attrs : {
103114 // We only add a tabindex of 0 if there is a head-clicked listener
@@ -106,41 +117,42 @@ export default {
106117 title : field . headerTitle || null ,
107118 'aria-colindex' : colIndex + 1 ,
108119 'aria-label' : ariaLabel ,
109- ...this . getThValues ( null , field . key , field . thAttr , isFoot ? 'foot' : 'head' , { } ) ,
120+ ...this . getThValues ( null , key , field . thAttr , isFoot ? 'foot' : 'head' , { } ) ,
110121 ...sortAttrs
111122 } ,
112- on : handlers
123+ on,
124+ key
113125 }
126+
114127 // Handle edge case where in-document templates are used with new
115128 // `v-slot:name` syntax where the browser lower-cases the v-slot's
116129 // name (attributes become lower cased when parsed by the browser)
117130 // We have replaced the square bracket syntax with round brackets
118131 // to prevent confusion with dynamic slot names
119- let slotNames = [ `head(${ field . key } )` , `head(${ field . key . toLowerCase ( ) } )` , 'head()' ]
132+ let slotNames = [ `head(${ key } )` , `head(${ key . toLowerCase ( ) } )` , 'head()' ]
133+ // Footer will fallback to header slot names
120134 if ( isFoot ) {
121- // Footer will fallback to header slot names
122- slotNames = [
123- `foot(${ field . key } )` ,
124- `foot(${ field . key . toLowerCase ( ) } )` ,
125- 'foot()' ,
126- ...slotNames
127- ]
135+ slotNames = [ `foot(${ key } )` , `foot(${ key . toLowerCase ( ) } )` , 'foot()' , ...slotNames ]
128136 }
137+
129138 const scope = {
130- label : field . label ,
131- column : field . key ,
139+ label,
140+ column : key ,
132141 field,
133142 isFoot,
134143 // Add in row select methods
135144 selectAllRows,
136145 clearSelected
137146 }
138- const content =
147+
148+ const $content =
139149 this . normalizeSlot ( slotNames , scope ) ||
140- ( field . labelHtml ? h ( 'div' , { domProps : htmlOrText ( field . labelHtml ) } ) : field . label )
141- const srLabel = sortLabel ? h ( 'span' , { staticClass : 'sr-only' } , ` (${ sortLabel } )` ) : null
150+ h ( 'div' , { domProps : htmlOrText ( labelHtml , label ) } )
151+
152+ const $srLabel = sortLabel ? h ( 'span' , { staticClass : 'sr-only' } , ` (${ sortLabel } )` ) : null
153+
142154 // Return the header cell
143- return h ( BTh , data , [ content , srLabel ] . filter ( identity ) )
155+ return h ( BTh , data , [ $ content, $ srLabel] . filter ( identity ) )
144156 }
145157
146158 // Generate the array of <th> cells
@@ -149,23 +161,39 @@ export default {
149161 // Generate the row(s)
150162 const $trs = [ ]
151163 if ( isFoot ) {
152- const trProps = {
153- variant : isUndefinedOrNull ( this . footRowVariant )
154- ? this . headRowVariant
155- : /* istanbul ignore next */ this . footRowVariant
156- }
157- $trs . push ( h ( BTr , { class : this . tfootTrClass , props : trProps } , $cells ) )
164+ $trs . push (
165+ h (
166+ BTr ,
167+ {
168+ class : this . tfootTrClass ,
169+ props : {
170+ variant : isUndefinedOrNull ( footRowVariant )
171+ ? headRowVariant
172+ : /* istanbul ignore next */ footRowVariant
173+ }
174+ } ,
175+ $cells
176+ )
177+ )
158178 } else {
159179 const scope = {
160180 columns : fields . length ,
161- fields : fields ,
181+ fields,
162182 // Add in row select methods
163183 selectAllRows,
164184 clearSelected
165185 }
166186 $trs . push ( this . normalizeSlot ( 'thead-top' , scope ) || h ( ) )
187+
167188 $trs . push (
168- h ( BTr , { class : this . theadTrClass , props : { variant : this . headRowVariant } } , $cells )
189+ h (
190+ BTr ,
191+ {
192+ class : this . theadTrClass ,
193+ props : { variant : headRowVariant }
194+ } ,
195+ $cells
196+ )
169197 )
170198 }
171199
@@ -175,8 +203,8 @@ export default {
175203 key : isFoot ? 'bv-tfoot' : 'bv-thead' ,
176204 class : ( isFoot ? this . tfootClass : this . theadClass ) || null ,
177205 props : isFoot
178- ? { footVariant : this . footVariant || this . headVariant || null }
179- : { headVariant : this . headVariant || null }
206+ ? { footVariant : footVariant || headVariant || null }
207+ : { headVariant : headVariant || null }
180208 } ,
181209 $trs
182210 )
0 commit comments