Skip to content

Commit

Permalink
perf(table): improve provide/inject performance (addresses #4155) (#4164
Browse files Browse the repository at this point in the history
)
  • Loading branch information
tmorehouse committed Sep 30, 2019
1 parent 119ceb3 commit 152fefc
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 50 deletions.
32 changes: 30 additions & 2 deletions src/components/table/tbody.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,44 @@ export const BTbody = /*#__PURE__*/ Vue.extend({
inheritAttrs: false,
provide() {
return {
bvTableTbody: this
bvTableRowGroup: this
}
},
inject: {
bvTable: {
default: null
// Sniffed by <b-tr> / <b-td> / <b-th>
default() /* istanbul ignore next */ {
return {}
}
}
},
props,
computed: {
isTbody() {
// Sniffed by <b-tr> / <b-td> / <b-th>
return true
},
isDark() {
// Sniffed by <b-tr> / <b-td> / <b-th>
return this.bvTable.dark
},
isStacked() {
// Sniffed by <b-tr> / <b-td> / <b-th>
return this.bvTable.isStacked
},
isResponsive() {
// Sniffed by <b-tr> / <b-td> / <b-th>
return this.bvTable.isResponsive
},
isStickyHeader() {
// Sniffed by <b-tr> / <b-td> / <b-th>
// Sticky headers are only supported in thead
return false
},
tableVariant() /* istanbul ignore next: Not currently sniffed in tests */ {
// Sniffed by <b-tr> / <b-td> / <b-th>
return this.bvTable.tableVariant
},
isTransitionGroup() {
return this.tbodyTransitionProps || this.tbodyTransitionHandlers
},
Expand Down
81 changes: 40 additions & 41 deletions src/components/table/td.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,21 +45,10 @@ export const BTd = /*#__PURE__*/ Vue.extend({
mixins: [normalizeSlotMixin],
inheritAttrs: false,
inject: {
// Injections for feature / attribute detection
bvTable: {
default: null
},
bvTableTbody: {
default: null
},
bvTableThead: {
default: null
},
bvTableTfoot: {
default: null
},
bvTableTr: {
default: null
default() /* istanbul ignore next */ {
return {}
}
}
},
props,
Expand All @@ -68,72 +57,82 @@ export const BTd = /*#__PURE__*/ Vue.extend({
// Overridden by <b-th>
return 'td'
},
inTbody() {
return this.bvTableTr.inTbody
},
inThead() {
return this.bvTableTr.inThead
},
inTfoot() {
return this.bvTableTr.inTfoot
},
isDark() {
return this.bvTable && this.bvTable.dark
return this.bvTableTr.isDark
},
isStacked() {
return this.bvTable && this.bvTable.isStacked
return this.bvTableTr.isStacked
},
isStackedCell() {
// We only support stacked-heading in tbody in stacked mode
return this.bvTableTbody && this.isStacked
return this.inTbody && this.isStacked
},
isResponsive() {
return this.bvTable && this.bvTable.isResponsive && !this.isStacked
return this.bvTableTr.isResponsive
},
isStickyHeader() {
// Needed to handle header background classes, due to lack of
// background color inheritance with Bootstrap v4 table CSS
// Sticky headers only apply to cells in table `thead`
return (
!this.isStacked &&
this.bvTable &&
this.bvTableThead &&
this.bvTableTr &&
this.bvTable.stickyHeader
)
return this.bvTableTr.isStickyHeader
},
isStickyColumn() {
// Needed to handle header background classes, due to lack of
// background color inheritance with Bootstrap v4 table CSS
// Sticky column cells are only available in responsive
// mode (horizontal scrolling) or when sticky header mode
// Applies to cells in `thead`, `tbody` and `tfoot`
return (
(this.isResponsive || this.isStickyHeader) &&
this.stickyColumn &&
!this.isStacked &&
this.bvTable &&
this.bvTableTr
)
return !this.isStacked && (this.isResponsive || this.isStickyHeader) && this.stickyColumn
},
rowVariant() {
return this.bvTableTr.variant
},
headVariant() {
return this.bvTableTr.headVariant
},
footVariant() /* istanbul ignore next: need to add in tests for footer variant */ {
return this.bvTableTr.footVariant
},
tableVariant() {
return this.bvTableTr.tableVariant
},
computedColspan() {
return parseSpan(this.colspan)
},
computedRowspan() {
return parseSpan(this.rowspan)
},
cellClasses() {
// We use computed props here for improved performance by caching
// the results of the string interpolation
// TODO: need to add handling for footVariant
let variant = this.variant
if (
(!variant && this.isStickyHeader && !this.bvTableThead.headVariant) ||
(!variant && this.isStickyHeader && !this.headVariant) ||
(!variant && this.isStickyColumn)
) {
// Needed for sticky-header mode as Bootstrap v4 table cells do
// not inherit parent's background-color. Boo!
variant = this.bvTableTr.variant || this.bvTable.tableVariant || 'b-table-default'
variant = this.rowVariant || this.tableVariant || 'b-table-default'
}
return [
variant ? `${this.isDark ? 'bg' : 'table'}-${variant}` : null,
this.isStickyColumn ? 'b-table-sticky-column' : null
]
},
computedColspan() {
return parseSpan(this.colspan)
},
computedRowspan() {
return parseSpan(this.rowspan)
},
cellAttrs() {
// We use computed props here for improved performance by caching
// the results of the object spread (Object.assign)
const headOrFoot = this.bvTableThead || this.bvTableTfoot
const headOrFoot = this.inThead || this.inTfoot
// Make sure col/rowspan's are > 0 or null
const colspan = this.computedColspan
const rowspan = this.computedRowspan
Expand Down
32 changes: 30 additions & 2 deletions src/components/table/tfoot.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,44 @@ export const BTfoot = /*#__PURE__*/ Vue.extend({
inheritAttrs: false,
provide() {
return {
bvTableTfoot: this
bvTableRowGroup: this
}
},
inject: {
bvTable: {
default: null
// Sniffed by <b-tr> / <b-td> / <b-th>
default() /* istanbul ignore next */ {
return {}
}
}
},
props,
computed: {
isTfoot() {
// Sniffed by <b-tr> / <b-td> / <b-th>
return true
},
isDark() /* istanbul ignore next: Not currently sniffed in tests */ {
// Sniffed by <b-tr> / <b-td> / <b-th>
return this.bvTable.dark
},
isStacked() {
// Sniffed by <b-tr> / <b-td> / <b-th>
return this.bvTable.isStacked
},
isResponsive() {
// Sniffed by <b-tr> / <b-td> / <b-th>
return this.bvTable.isResponsive
},
isStickyHeader() {
// Sniffed by <b-tr> / <b-td> / <b-th>
// Sticky headers are only supported in thead
return false
},
tableVariant() /* istanbul ignore next: Not currently sniffed in tests */ {
// Sniffed by <b-tr> / <b-td> / <b-th>
return this.bvTable.tableVariant
},
tfootClasses() {
return [this.footVariant ? `thead-${this.footVariant}` : null]
},
Expand Down
35 changes: 33 additions & 2 deletions src/components/table/thead.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import normalizeSlotMixin from '../../mixins/normalize-slot'

export const props = {
headVariant: {
// Also sniffed by <b-tr> / <b-td> / <b-th>
type: String, // supported values: 'lite', 'dark', or null
default: null
}
Expand All @@ -15,16 +16,46 @@ export const BThead = /*#__PURE__*/ Vue.extend({
inheritAttrs: false,
provide() {
return {
bvTableThead: this
bvTableRowGroup: this
}
},
inject: {
bvTable: {
default: null
// Sniffed by <b-tr> / <b-td> / <b-th>
default() /* istanbul ignore next */ {
return {}
}
}
},
props,
computed: {
isThead() {
// Sniffed by <b-tr> / <b-td> / <b-th>
return true
},
isDark() {
// Sniffed by <b-tr> / <b-td> / <b-th>
return this.bvTable.dark
},
isStacked() {
// Sniffed by <b-tr> / <b-td> / <b-th>
return this.bvTable.isStacked
},
isResponsive() {
// Sniffed by <b-tr> / <b-td> / <b-th>
return this.bvTable.isResponsive
},
isStickyHeader() {
// Sniffed by <b-tr> / <b-td> / <b-th>
// Needed to handle header background classes, due to lack of
// background color inheritance with Bootstrap v4 table CSS
// Sticky headers only apply to cells in table `thead`
return !this.isStacked && this.bvTable.stickyHeader
},
tableVariant() {
// Sniffed by <b-tr> / <b-td> / <b-th>
return this.bvTable.tableVariant
},
theadClasses() {
return [this.headVariant ? `thead-${this.headVariant}` : null]
},
Expand Down
42 changes: 39 additions & 3 deletions src/components/table/tr.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,50 @@ export const BTr = /*#__PURE__*/ Vue.extend({
}
},
inject: {
bvTable: {
default: null
bvTableRowGroup: {
defaut() /* istanbul ignore next */ {
return {}
}
}
},
props,
computed: {
inTbody() {
// Sniffed by <b-td> / <b-th>
return this.bvTableRowGroup.isTbody
},
inThead() {
// Sniffed by <b-td> / <b-th>
return this.bvTableRowGroup.isThead
},
inTfoot() {
// Sniffed by <b-td> / <b-th>
return this.bvTableRowGroup.isTfoot
},
isDark() {
return this.bvTable && this.bvTable.dark
// Sniffed by <b-td> / <b-th>
return this.bvTableRowGroup.isDark
},
isStacked() {
// Sniffed by <b-td> / <b-th>
return this.bvTableRowGroup.isStacked
},
isResponsive() {
// Sniffed by <b-td> / <b-th>
return this.bvTableRowGroup.isResponsive
},
isStickyHeader() {
// Sniffed by <b-td> / <b-th>
// Sticky headers are only supported in thead
return this.bvTableRowGroup.isStickyHeader
},
tableVariant() {
// Sniffed by <b-td> / <b-th>
return this.bvTableRowGroup.tableVariant
},
headVariant() {
// Sniffed by <b-td> / <b-th>
return this.bvTableRowGroup.headVariant
},
trClasses() {
return [this.variant ? `${this.isDark ? 'bg' : 'table'}-${this.variant}` : null]
Expand Down

0 comments on commit 152fefc

Please sign in to comment.