Skip to content

Commit

Permalink
chore(lib): partially update Table
Browse files Browse the repository at this point in the history
- In `src/components/table/Table.vue`,
    - The code to generate default renderers for `columns` is totally
      replaced. I thought the older code cannot be ported to Vue 3
      because Vue 3 no longer provides `extend` and I could not find
      out how to get a component instance without mounting it. Thus
      I decided to create an object that mocks a component instance.
      `mockTableColumn` does it. `mockTableColumn` creates an object
      that conforms to the interface required by `SlotComponent`.
    - The bug that `Table` crashed when `$slots.footer` was not
      specified is fixed.
- Background: enough updates to show the documentation page of the
  `Button` component are performed. The documentation page uses the
  `Table` component to show attributes and events of the `Button`
  component.
- TODO: the `mockTableColumn` function should be defined in a
  separate file.
- Applies ESLint fix to the following files,
    - `src/components/input/Input.vue`
    - `src/components/pagination/Pagination.vue`
    - `src/components/pagination/PaginationButton.vue`
    - `src/components/table/TableColumn.vue`
    - `src/components/table/TableMobileSort.vue`
    - `src/utils/FormElementMixin.js`
- Manually fixes the following ESLint errors,
    - Removing `.native` from `v-on` (`Input`)
    - Explicitly returning `undefined` (`Input`, `PaginationButton`)
    - Avoiding combinations of `v-for` and `v-if` (`TableMobileSort`).
      Removes `v-if` by filtering the array before giving it to `v-for`.
  • Loading branch information
kikuomax committed Jul 6, 2023
1 parent bd1fe22 commit 017531f
Show file tree
Hide file tree
Showing 7 changed files with 173 additions and 50 deletions.
16 changes: 11 additions & 5 deletions src/components/input/Input.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
@input="onInput"
@change="onChange"
@blur="onBlur"
@focus="onFocus">
@focus="onFocus"
>

<textarea
v-else
Expand All @@ -29,7 +30,8 @@
@input="onInput"
@change="onChange"
@blur="onBlur"
@focus="onFocus"/>
@focus="onFocus"
/>

<b-icon
v-if="icon"
Expand All @@ -38,7 +40,8 @@
:icon="icon"
:pack="iconPack"
:size="iconSize"
@click.native="iconClick('icon-click', $event)"/>
@click="iconClick('icon-click', $event)"
/>

<b-icon
v-if="!loading && hasIconRight"
Expand All @@ -49,12 +52,14 @@
:size="iconSize"
:type="rightIconType"
both
@click.native="rightIconClick"/>
@click="rightIconClick"
/>

<small
v-if="maxlength && hasCounter && type !== 'number'"
class="help counter"
:class="{ 'is-invisible': !isFocused }">
:class="{ 'is-invisible': !isFocused }"
>
{{ valueLength }} / {{ maxlength }}
</small>
</div>
Expand Down Expand Up @@ -182,6 +187,7 @@ export default {
case 'is-danger': return 'alert-circle'
case 'is-info': return 'information'
case 'is-warning': return 'alert'
default: return undefined
}
},
Expand Down
26 changes: 15 additions & 11 deletions src/components/pagination/Pagination.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<nav class="pagination" :class="rootClasses">
<slot
v-if="$scopedSlots.previous"
v-if="$slots.previous"
name="previous"
:page="
getPage(current - 1, {
Expand All @@ -15,7 +15,8 @@
:icon="iconPrev"
:pack="iconPack"
both
aria-hidden="true" />
aria-hidden="true"
/>
</slot>
<BPaginationButton
v-else
Expand All @@ -28,10 +29,11 @@
:icon="iconPrev"
:pack="iconPack"
both
aria-hidden="true" />
aria-hidden="true"
/>
</BPaginationButton>
<slot
v-if="$scopedSlots.next"
v-if="$slots.next"
name="next"
:page="
getPage(current + 1, {
Expand All @@ -45,7 +47,8 @@
:icon="iconNext"
:pack="iconPack"
both
aria-hidden="true" />
aria-hidden="true"
/>
</slot>
<BPaginationButton
v-else
Expand All @@ -58,7 +61,8 @@
:icon="iconNext"
:pack="iconPack"
both
aria-hidden="true" />
aria-hidden="true"
/>
</BPaginationButton>

<div class="control pagination-input">
Expand All @@ -82,7 +86,7 @@
<ul class="pagination-list" v-else>
<!--First-->
<li v-if="hasFirst">
<slot v-if="$scopedSlots.default" :page="getPage(1)" />
<slot v-if="$slots.default" :page="getPage(1)" />
<BPaginationButton v-else :page="getPage(1)" />
</li>
<li v-if="hasFirstEllipsis">
Expand All @@ -91,7 +95,7 @@

<!--Pages-->
<li v-for="page in pagesInRange" :key="page.number">
<slot v-if="$scopedSlots.default" :page="page" />
<slot v-if="$slots.default" :page="page" />
<BPaginationButton v-else :page="page" />
</li>

Expand All @@ -100,7 +104,7 @@
<span class="pagination-ellipsis">&hellip;</span>
</li>
<li v-if="hasLast">
<slot v-if="$scopedSlots.default" :page="getPage(pageCount)" />
<slot v-if="$slots.default" :page="getPage(pageCount)" />
<BPaginationButton v-else :page="getPage(pageCount)" />
</li>
</ul>
Expand Down Expand Up @@ -384,7 +388,7 @@ export default {
handleOnKeyPress(event) {
// --- This is required to only allow numeric inputs for the page input - --- //
// --- size attribute does not work with input type number. --- //
let ASCIICode = event.which || event.keyCode
const ASCIICode = event.which || event.keyCode
if (ASCIICode >= 48 && ASCIICode <= 57) {
return true
Expand All @@ -404,7 +408,7 @@ export default {
}
},
handleOnInputValue(event) {
let inputValue = +event.target.value
const inputValue = +event.target.value
this.inputValue = inputValue
if (Number.isInteger(this.inputValue)) {
this.handleOnInputDebounce(event)
Expand Down
4 changes: 3 additions & 1 deletion src/components/pagination/PaginationButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
v-bind="$attrs"
@click.prevent="page.click"
:aria-label="page['aria-label']"
:aria-current="page.isCurrent">
:aria-current="page.isCurrent"
>
<slot>{{ page.number }}</slot>
</component>
</template>
Expand Down Expand Up @@ -41,6 +42,7 @@ export default {
if (this.tag === 'a') {
return '#'
}
return undefined
},
isDisabled() {
return this.disabled || this.page.disabled
Expand Down
127 changes: 114 additions & 13 deletions src/components/table/Table.vue
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@
</tr>
</tbody>

<tfoot v-if="$slots.footer() !== undefined">
<tfoot v-if="$slots.footer !== undefined">
<tr class="table-footer">
<slot name="footer" v-if="hasCustomFooterSlot()" />
<th :colspan="columnCount" v-else>
Expand Down Expand Up @@ -419,9 +419,11 @@
</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 { VueInstance } from '../../utils/config'
import Checkbox from '../checkbox/Checkbox.vue'
import Icon from '../icon/Icon.vue'
import Input from '../input/Input.vue'
Expand Down Expand Up @@ -789,21 +791,118 @@ export default {
newColumns() {
if (this.columns && this.columns.length) {
return this.columns.map((column) => {
const TableColumnComponent = VueInstance.extend(TableColumn)
const component = new TableColumnComponent(
{ parent: this, propsData: column }
)
component.$scopedSlots = {
default: (props) => {
const vnode = component.$createElement('span', {
domProps: {
innerHTML: getValueByPath(props.row, column.field)
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
})
return [vnode]
}
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 component
return mockTableColumn(column)
})
}
return this.defaultSlots
Expand Down Expand Up @@ -1289,6 +1388,8 @@ export default {
/**
* Check if footer slot has custom content.
*
* Assumes that `$slots.footer` is specified.
*/
hasCustomFooterSlot() {
if (this.$slots.footer().length > 1) return true
Expand Down
4 changes: 2 additions & 2 deletions src/components/table/TableColumn.vue
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export default {
}
},
hasDefaultSlot() {
return !!this.$scopedSlots.default
return !!this.$slots.default
},
/**
* Return if column header is un-selectable
Expand Down Expand Up @@ -110,7 +110,7 @@ export default {
}
this.$table.refreshSlots()
},
beforeDestroy() {
beforeUnmount() {
this.$table.refreshSlots()
},
render(createElement) {
Expand Down

0 comments on commit 017531f

Please sign in to comment.