UNPKG

vuetify

Version:

Vue.js 2 Semantic Component Framework

139 lines (122 loc) 4.09 kB
import { consoleWarn } from '../../../util/console' import VCheckbox from '../../VCheckbox' import VIcon from '../../VIcon' /* @vue/component */ export default { props: { sortIcon: { type: String, default: '$vuetify.icons.sort' } }, methods: { genTHead () { if (this.hideHeaders) return // Exit Early since no headers are needed. let children = [] if (this.$scopedSlots.headers) { const row = this.$scopedSlots.headers({ headers: this.headers, indeterminate: this.indeterminate, all: this.everyItem }) children = [this.hasTag(row, 'th') ? this.genTR(row) : row, this.genTProgress()] } else { const row = this.headers.map((o, i) => this.genHeader(o, this.headerKey ? o[this.headerKey] : i)) const checkbox = this.$createElement(VCheckbox, { props: { dark: this.dark, light: this.light, color: this.selectAll === true ? '' : this.selectAll, hideDetails: true, inputValue: this.everyItem, indeterminate: this.indeterminate }, on: { change: this.toggle } }) this.hasSelectAll && row.unshift(this.$createElement('th', [checkbox])) children = [this.genTR(row), this.genTProgress()] } return this.$createElement('thead', [children]) }, genHeader (header, key) { const array = [ this.$scopedSlots.headerCell ? this.$scopedSlots.headerCell({ header }) : header[this.headerText] ] return this.$createElement('th', ...this.genHeaderData(header, array, key)) }, genHeaderData (header, children, key) { const classes = ['column'] const data = { key, attrs: { role: 'columnheader', scope: 'col', width: header.width || null, 'aria-label': header[this.headerText] || '', 'aria-sort': 'none' } } if (header.sortable == null || header.sortable) { this.genHeaderSortingData(header, children, data, classes) } else { data.attrs['aria-label'] += ': Not sorted.' // TODO: Localization } classes.push(`text-xs-${header.align || 'left'}`) if (Array.isArray(header.class)) { classes.push(...header.class) } else if (header.class) { classes.push(header.class) } data.class = classes return [data, children] }, genHeaderSortingData (header, children, data, classes) { if (!('value' in header)) { consoleWarn('Headers must have a value property that corresponds to a value in the v-model array', this) } data.attrs.tabIndex = 0 data.on = { click: () => { this.expanded = {} this.sort(header.value) }, keydown: e => { // check for space if (e.keyCode === 32) { e.preventDefault() this.sort(header.value) } } } classes.push('sortable') const icon = this.$createElement(VIcon, { props: { small: true } }, this.sortIcon) if (!header.align || header.align === 'left') { children.push(icon) } else { children.unshift(icon) } const pagination = this.computedPagination const beingSorted = pagination.sortBy === header.value if (beingSorted) { classes.push('active') if (pagination.descending) { classes.push('desc') data.attrs['aria-sort'] = 'descending' data.attrs['aria-label'] += ': Sorted descending. Activate to remove sorting.' // TODO: Localization } else { classes.push('asc') data.attrs['aria-sort'] = 'ascending' data.attrs['aria-label'] += ': Sorted ascending. Activate to sort descending.' // TODO: Localization } } else { data.attrs['aria-label'] += ': Not sorted. Activate to sort ascending.' // TODO: Localization } } } }