1
1
import Vue from '../../utils/vue'
2
-
import { omit } from '../../utils/object'
3
-
import { props as cellProps, BTableCell } from './helpers/table-cell'
2
+
import toString from '../../utils/to-string'
3
+
import { isUndefinedOrNull } from '../../utils/inspect'
4
+
import normalizeSlotMixin from '../../mixins/normalize-slot'
4
5
5
-
export const props = omit(cellProps, ['header'])
6
+
const digitsRx = /^\d+$/
7
+
8
+
// Parse a rowspan or colspan into a digit (or null if < 1 or NaN)
9
+
const parseSpan = val => {
10
+
val = parseInt(val, 10)
11
+
return digitsRx.test(String(val)) && val > 0 ? val : null
12
+
}
13
+
14
+
/* istanbul ignore next */
15
+
const spanValidator = val => isUndefinedOrNull(val) || parseSpan(val) > 0
16
+
17
+
export const props = {
18
+
variant: {
19
+
type: String,
20
+
default: null
21
+
},
22
+
colspan: {
23
+
type: [Number, String],
24
+
default: null,
25
+
validator: spanValidator
26
+
},
27
+
rowspan: {
28
+
type: [Number, String],
29
+
default: null,
30
+
validator: spanValidator
31
+
},
32
+
stackedHeading: {
33
+
type: String,
34
+
default: null
35
+
},
36
+
stickyColumn: {
37
+
type: Boolean,
38
+
default: false
39
+
}
40
+
}
6
41
7
42
// @vue/component
8
43
export const BTd = /*#__PURE__*/ Vue.extend({
9
-
name: 'BTd',
10
-
functional: true,
44
+
name: 'BTableCell',
45
+
mixins: [normalizeSlotMixin],
46
+
inheritAttrs: false,
47
+
inject: {
48
+
// Injections for feature / attribute detection
49
+
bvTable: {
50
+
default: null
51
+
},
52
+
bvTableTbody: {
53
+
default: null
54
+
},
55
+
bvTableThead: {
56
+
default: null
57
+
},
58
+
bvTableTfoot: {
59
+
default: null
60
+
},
61
+
bvTableTr: {
62
+
default: null
63
+
}
64
+
},
11
65
props,
12
-
render(h, { props, data, children }) {
13
-
// `data` already includes any listeners
14
-
data.props = { ...props, header: false }
15
-
return h(BTableCell, data, children)
66
+
computed: {
67
+
tag() {
68
+
// Overridden by <b-th>
69
+
return 'td'
70
+
},
71
+
isDark() {
72
+
return this.bvTable && this.bvTable.dark
73
+
},
74
+
isStacked() {
75
+
return this.bvTable && this.bvTable.isStacked
76
+
},
77
+
isStackedCell() {
78
+
// We only support stacked-heading in tbody in stacked mode
79
+
return this.bvTableTbody && this.isStacked
80
+
},
81
+
isResponsive() {
82
+
return this.bvTable && this.bvTable.isResponsive && !this.isStacked
83
+
},
84
+
isStickyHeader() {
85
+
// Needed to handle header background classes, due to lack of
86
+
// background color inheritance with Bootstrap v4 table CSS
87
+
// Sticky headers only apply to cells in table `thead`
88
+
return (
89
+
!this.isStacked &&
90
+
this.bvTable &&
91
+
this.bvTableThead &&
92
+
this.bvTableTr &&
93
+
this.bvTable.stickyHeader
94
+
)
95
+
},
96
+
isStickyColumn() {
97
+
// Needed to handle header background classes, due to lack of
98
+
// background color inheritance with Bootstrap v4 table CSS
99
+
// Sticky column cells are only available in responsive
100
+
// mode (horizontal scrolling) or when sticky header mode
101
+
// Applies to cells in `thead`, `tbody` and `tfoot`
102
+
return (
103
+
(this.isResponsive || this.isStickyHeader) &&
104
+
this.stickyColumn &&
105
+
!this.isStacked &&
106
+
this.bvTable &&
107
+
this.bvTableTr
108
+
)
109
+
},
110
+
cellClasses() {
111
+
// We use computed props here for improved performance by caching
112
+
// the results of the string interpolation
113
+
let variant = this.variant
114
+
if (
115
+
(!variant && this.isStickyHeader && !this.bvTableThead.headVariant) ||
116
+
(!variant && this.isStickyColumn)
117
+
) {
118
+
// Needed for sticky-header mode as Bootstrap v4 table cells do
119
+
// not inherit parent's background-color. Boo!
120
+
variant = this.bvTableTr.variant || this.bvTable.tableVariant || 'b-table-default'
121
+
}
122
+
return [
123
+
variant ? `${this.isDark ? 'bg' : 'table'}-${variant}` : null,
124
+
this.isStickyColumn ? 'b-table-sticky-column' : null
125
+
]
126
+
},
127
+
computedColspan() {
128
+
return parseSpan(this.colspan)
129
+
},
130
+
computedRowspan() {
131
+
return parseSpan(this.rowspan)
132
+
},
133
+
cellAttrs() {
134
+
// We use computed props here for improved performance by caching
135
+
// the results of the object spread (Object.assign)
136
+
const headOrFoot = this.bvTableThead || this.bvTableTfoot
137
+
// Make sure col/rowspan's are > 0 or null
138
+
const colspan = this.computedColspan
139
+
const rowspan = this.computedRowspan
140
+
// Default role and scope
141
+
let role = 'cell'
142
+
let scope = null
143
+
144
+
// Compute role and scope
145
+
// We only add scopes with an explicit span of 1 or greater
146
+
if (headOrFoot) {
147
+
// Header or footer cells
148
+
role = 'columnheader'
149
+
scope = colspan > 0 ? 'colspan' : 'col'
150
+
} else if (this.tag === 'th') {
151
+
// th's in tbody
152
+
role = 'rowheader'
153
+
scope = rowspan > 0 ? 'rowgroup' : 'row'
154
+
}
155
+
156
+
return {
157
+
colspan: colspan,
158
+
rowspan: rowspan,
159
+
role: role,
160
+
scope: scope,
161
+
// Allow users to override role/scope plus add other attributes
162
+
...this.$attrs,
163
+
// Add in the stacked cell label data-attribute if in
164
+
// stacked mode (if a stacked heading label is provided)
165
+
'data-label':
166
+
this.isStackedCell && !isUndefinedOrNull(this.stackedHeading)
167
+
? toString(this.stackedHeading)
168
+
: null
169
+
}
170
+
}
171
+
},
172
+
render(h) {
173
+
const content = [this.normalizeSlot('default')]
174
+
return h(
175
+
this.tag,
176
+
{
177
+
class: this.cellClasses,
178
+
attrs: this.cellAttrs,
179
+
// Transfer any native listeners
180
+
on: this.$listeners
181
+
},
182
+
[this.isStackedCell ? h('div', [content]) : content]
183
+
)
16
184
}
17
185
})
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4