Skip to content

Commit

Permalink
chore(lib): separate mockTableColumn
Browse files Browse the repository at this point in the history
- `mockTableColumn` is separated from `Table.vue` and defined in
  `src/components/table/mockTableColumn.js`. `mockTableColumn` is made
  as simple as it uses neither `ref` nor `computed` because I do not
  think reactivity is necessary. Maybe I am wrong but let's see.
  • Loading branch information
kikuomax committed Jul 6, 2023
1 parent 017531f commit ea627f6
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 115 deletions.
117 changes: 2 additions & 115 deletions src/components/table/Table.vue
Original file line number Diff line number Diff line change
Expand Up @@ -419,9 +419,6 @@
</template>

<script>
import { ref, computed, h as createElement } from 'vue'
import Emitter from 'tiny-emitter'
import { getValueByPath, indexOf, multiColumnSort, escapeRegExpChars, toCssWidth, removeDiacriticsFromString, isNil } from '../../utils/helpers'
import debounce from '../../utils/debounce'
import Checkbox from '../checkbox/Checkbox.vue'
Expand All @@ -432,6 +429,7 @@ import SlotComponent from '../../utils/SlotComponent'
import TableMobileSort from './TableMobileSort.vue'
import TableColumn from './TableColumn.vue'
import TablePagination from './TablePagination.vue'
import mockTableColumn from './mockTableColumn'
export default {
name: 'BTable',
Expand Down Expand Up @@ -791,118 +789,7 @@ export default {
newColumns() {
if (this.columns && this.columns.length) {
return this.columns.map((column) => {
const mockTableColumn = (column) => {
const eventEmitter = new Emitter()
const self = {
parent: this,
getRootClasses(row) {
const attrs = this.tdAttrs(row, this)
const classes = [this.rootClasses]
if (attrs && attrs.class) {
classes.push(attrs.class)
}
return classes
},
getRootStyle(row) {
const attrs = this.tdAttrs(row, this)
const style = []
if (attrs && attrs.style) {
style.push(attrs.style)
}
return style
},
$on: (...args) => eventEmitter.on(...args),
$once: (...args) => eventEmitter.once(...args),
$off: (...args) => eventEmitter.off(...args),
$emit: (...args) => eventEmitter.emit(...args)
} // other properties are assigned later
const defaultProps = {
label: undefined,
customKey: undefined,
field: undefined,
meta: undefined,
width: undefined,
numeric: undefined,
centered: undefined,
searchable: undefined,
sortable: undefined,
visible: true,
subheading: undefined,
customSort: undefined,
customSearch: undefined,
sticky: undefined,
headerSelectable: undefined,
headerClass: undefined,
thAttrs: () => ({}),
tdAttrs: () => ({})
}
const columnRef = ref({
...defaultProps,
...column
})
const computedProps = {
thClasses: computed(() => {
const attrs = self.thAttrs(self)
const classes = [self.headerClass, {
'is-sortable': self.sortable,
'is-sticky': self.sticky,
'is-unselectable': self.isHeaderUnSelectable
}]
if (attrs && attrs.class) {
classes.push(attrs.class)
}
return classes
}),
thStyle: computed(() => {
const attrs = self.thAttrs(self)
const style = [self.style]
if (attrs && attrs.style) {
style.push(attrs.style)
}
return style
}),
rootClasses: computed(() => {
return [self.cellClass, {
'has-text-right': self.numeric && !self.centered,
'has-text-centered': self.centered,
'is-sticky': self.sticky
}]
}),
style: computed(() => {
return {
width: toCssWidth(self.width)
}
}),
hasDefaultSlot: computed(() => {
return !!self.$scopedSlots.default
}),
isHeaderUnSelectable: computed(() => {
return !self.headerSelectable && self.sortable
})
}
for (const key in defaultProps) {
Object.defineProperty(self, key, {
get: () => columnRef.value[key]
})
}
for (const key in computedProps) {
Object.defineProperty(self, key, {
get: () => computedProps[key].value
})
}
self.$scopedSlots = {
default: (props) => {
const vnode = createElement('span', {
innerHTML: getValueByPath(props.row, column.field)
})
return [vnode]
}
}
self._isVue = true
self.$table = this
return self
}
return mockTableColumn(column)
return mockTableColumn(this, column)
})
}
return this.defaultSlots
Expand Down
109 changes: 109 additions & 0 deletions src/components/table/mockTableColumn.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { h as createElement } from 'vue'
import Emitter from 'tiny-emitter'

import { getValueByPath, toCssWidth } from '../../utils/helpers'

export default function mockTableColumn(table, column) {
const eventEmitter = new Emitter()
const defaultProps = {
label: undefined,
customKey: undefined,
field: undefined,
meta: undefined,
width: undefined,
numeric: undefined,
centered: undefined,
searchable: undefined,
sortable: undefined,
visible: true,
subheading: undefined,
customSort: undefined,
customSearch: undefined,
sticky: undefined,
headerSelectable: undefined,
headerClass: undefined,
thAttrs: () => ({}),
tdAttrs: () => ({})
}
return {
// props
...defaultProps,
...column,
// data
parent: table,
newKey: column.customKey || column.label,
_isTableColumn: true,
// inject
$table: table,
// computed
get thClasses() {
const attrs = this.thAttrs(this)
const classes = [this.headerClass, {
'is-sortable': this.sortable,
'is-sticky': this.sticky,
'is-unselectable': this.isHeaderUnSelectable
}]
if (attrs && attrs.class) {
classes.push(attrs.class)
}
return classes
},
get thStyle() {
const attrs = this.thAttrs(this)
const style = [this.style]
if (attrs && attrs.style) {
style.push(attrs.style)
}
return style
},
get rootClasses() {
return [this.cellClass, {
'has-text-right': this.numeric && !this.centered,
'has-text-centered': this.centered,
'is-sticky': this.sticky
}]
},
get style() {
return {
width: toCssWidth(this.width)
}
},
get hasDefaultSlot() {
return !!this.$scopedSlots.default
},
get isHeaderUnSelectable() {
return !this.headerSelectable && this.sortable
},
// methods
getRootClasses(row) {
const attrs = this.tdAttrs(row, this)
const classes = [this.rootClasses]
if (attrs && attrs.class) {
classes.push(attrs.class)
}
return classes
},
getRootStyle(row) {
const attrs = this.tdAttrs(row, this)
const style = []
if (attrs && attrs.style) {
style.push(attrs.style)
}
return style
},
$on: (...args) => eventEmitter.on(...args),
$once: (...args) => eventEmitter.once(...args),
$off: (...args) => eventEmitter.off(...args),
$emit: (...args) => eventEmitter.emit(...args),
// special fields
_isVue: true,
$scopedSlots: {
default: (props) => {
const vnode = createElement('span', {
innerHTML: getValueByPath(props.row, column.field)
})
return [vnode]
}
}
}
}

0 comments on commit ea627f6

Please sign in to comment.