vuikit
Version:
A Vuejs component library based on UIkit
622 lines (566 loc) • 15.8 kB
JavaScript
/**
* Vuikit 0.7.0
* (c) 2018 Miljan Aleksic
* @license MIT
*/
import { get, includes, isFunction, isObject, isUndefined, merge } from 'vuikit/core/util';
import { warn } from 'vuikit/core/helpers/debug';
import mergeData from 'vuikit/core/helpers/vue-data-merge';
var Row = {
functional: true,
props: ['row'],
render: function render (h, ref) {
var props = ref.props;
var children = ref.children;
var table = ref.parent;
var row = props.row;
return h('tr', {
class: [resolveClass(table.rowClass, row), {
'uk-active': table.isSelected(row)
}],
on: {
click: function (e) {
var isPrevented = e._vk_row_click_prevented;
var isIgnoredTag = e.target.tagName.match(/A|BUTTON/);
if (isPrevented || isIgnoredTag) {
return
}
table.$emit('click-row', row);
}
}
}, children)
}
}
function resolveClass (rowClass, row) {
return isFunction(rowClass)
? rowClass(row)
: rowClass
}
var Cell = {
functional: true,
props: ['col', 'row'],
render: function render (h, ref) {
var parent = ref.parent;
var data = ref.data;
var props = ref.props;
var col = props.col;
var render = get(col, 'componentOptions.Ctor.options.cellRender');
if (!render) {
warn('The VkTable Column is missing the cell render definition', parent);
return
}
var colProps = get(col, 'componentOptions.propsData', {});
var scopedSlots = get(col, 'data.scopedSlots', {});
return h({
functional: true,
render: render
}, {
scopedSlots: scopedSlots,
props: merge({}, props, colProps)
})
}
}
var Table$1 = {
functional: true,
render: function render (h, ref) {
var slots = ref.slots;
var props = ref.props;
var _slots = slots();
return h('table', {
class: ['uk-table', {
'uk-table-small': props.narrowed,
'uk-table-hover': props.hoverable,
'uk-table-divider': props.divided,
'uk-table-striped': props.striped,
'uk-table-justify': props.justified,
'uk-table-middle': props.middleAligned,
'uk-table-responsive': props.responsive
}]
}, [
_slots.head && h('thead', [ h('tr', _slots.head) ]),
_slots.body && h('tbody', _slots.body)
])
},
props: {
narrowed: {
type: Boolean,
default: false
},
middleAligned: {
type: Boolean,
default: false
},
divided: {
type: Boolean,
default: false
},
striped: {
type: Boolean,
default: false
},
hoverable: {
type: Boolean,
default: false
},
justified: {
type: Boolean,
default: false
},
responsive: {
type: Boolean,
default: false
}
}
}
var MixinSelect = {
methods: {
select: function select (row) {
var id = row._vk_id;
if (this.singleSelectable) {
this.updateSelection([id]);
return
}
var selectedRows = [].concat( this.selectedRows );
selectedRows.push(id);
this.updateSelection(selectedRows);
},
unselect: function unselect (row) {
var id = row._vk_id;
var index = this.selectedRows.indexOf(id);
var selectedRows = [].concat( this.selectedRows );
selectedRows.splice(index, 1);
this.updateSelection(selectedRows);
},
toggleSelection: function toggleSelection (row) {
this.isSelected(row)
? this.unselect(row)
: this.select(row);
},
toggleSelectionAll: function toggleSelectionAll () {
var selectedRows = [];
if (!this.allRowsSelected) {
selectedRows = this.rows.map(function (row) { return row._vk_id; });
}
this.updateSelection(selectedRows);
},
isSelected: function isSelected (row) {
return includes(this.selectedRows, row._vk_id)
},
updateSelection: function updateSelection (selectedRows) {
this.$emit('update:selectedRows', selectedRows);
}
},
computed: {
allRowsSelected: function allRowsSelected () {
if (this.selectedRows.length < this.rows.length) {
return false
}
var selected = this.rows.filter(this.isSelected);
return selected.length === this.rows.length
}
},
created: function created () {
if (this.rowSelectable) {
this.$on('click-row', this.toggleSelection);
}
}
}
var Table = {
name: 'Table',
components: { Row: Row, Cell: Cell },
mixins: [ MixinSelect ],
inheritAttrs: false,
props: merge({}, Table$1.props, {
data: {
type: Array,
required: true
},
rowKey: {
type: String,
default: 'id'
},
rowClass: {
type: Function
},
// required by column-sort
sortedBy: {
type: Object
},
// required by column-select
selectedRows: {
type: Array,
default: function () { return []; }
},
singleSelectable: {
type: Boolean,
default: false
},
rowSelectable: {
type: Boolean,
default: false
}
}),
data: function () { return ({
children: []
}); },
computed: {
// maps the data to table rows
rows: function rows () {
var this$1 = this;
return this.data.map(function (_row, index) {
var row = merge({}, _row);
row._vk_id = "" + (row[this$1.rowKey] || index);
return row
})
},
// returns the columns vnodes
columns: {
get: function get$$1 () {
// default slots excluding spaces and comments
var slots = (this.$slots.default || [])
.filter(function (node) { return node.tag && !node.isComment && !node.asyncFactory; });
return slots
},
cache: false
},
// checks if there is at least one column providing head data
isHeadDataProvided: function isHeadDataProvided () {
return this.columns.some(function (col) { return get(col, 'componentOptions.propsData.head'); })
}
},
render: function render (h) {
var this$1 = this;
var renderRow = function (row, index) { return h(Row, {
key: row._vk_id,
props: { row: row }
}, this$1.columns.map(function (col, i) { return h(Cell, {
key: i,
props: { col: col, row: row }
}); })); };
return h(Table$1, { props: this.$props }, [
this.isHeadDataProvided && h('template', { slot: 'head' }, this.columns),
h('template', { slot: 'body' }, this.rows.map(renderRow))
])
},
created: function created () {
// required, forces rows to rerender
// when children are available
this.children = this.$children;
}
}
var ColumnHead = {
functional: true,
props: {
shrinked: {
type: Boolean,
default: false
},
expanded: {
type: Boolean,
default: false
}
},
render: function render (h, ref) {
var data = ref.data;
var props = ref.props;
var children = ref.children;
var def = mergeData(data, {
class: {
'uk-table-shrink': props.shrinked,
'uk-table-expand': props.expanded
}
});
return h('th', def, children)
}
}
var Column = {render: function(){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('column-head',{class:['vk-table-column', _vm.headClass],attrs:{"shrinked":_vm.shrinked,"expanded":_vm.expanded}},[_vm._t("head",[_vm._v(_vm._s(_vm.head))])],2)},staticRenderFns: [],
name: 'TableColumn',
components: {
ColumnHead: ColumnHead
},
props: mergeData({}, ColumnHead.props, {
head: {
type: String
},
headClass: {
type: String
},
cell: {
type: String
},
cellClass: {
type: String
}
}),
cellRender: function (h, ref) {
var props = ref.props;
var parent = ref.parent;
var data = ref.data;
var row = props.row;
var cell = props.cell;
var cellClass = props.cellClass;
var scopedSlots = data.scopedSlots;
var cellValue = get(row, cell);
// support custom slots, fallback to default fn
var cellSlot = scopedSlots.cell || (function () { return cellValue; });
var emptySlot = scopedSlots.emptyCell || (function () { return ''; });
return h('td', {
class: cellClass
}, [
isUndefined(cellValue)
? emptySlot(row)
: cellSlot(cellValue, row)
])
}
}
var Arrow = {
functional: true,
props: {
rotated: {
type: Boolean,
default: false
}
},
render: function (h, ref) {
var data = ref.data;
var props = ref.props;
return h('span', mergeData(data, {
class: ['vk-table-column-sort__arrow', {
'vk-table-column-sort__arrow--rotated': props.rotated
}]
}));
}
}
var sort = {render: function(){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('column-head',{class:['vk-table-column-sort uk-visible-hover-inline', _vm.headClass],attrs:{"shrinked":_vm.shrinked,"expanded":_vm.expanded},on:{"click":_vm.emitSortEvent}},[_c('div',{staticClass:"uk-text-nowrap uk-position-relative"},[_vm._t("head",[_vm._v(_vm._s(_vm.head))]),_vm._v(" "),_c('arrow',{class:['uk-position-absolute', { 'uk-invisible': !_vm.order }],attrs:{"rotated":_vm.order === 'asc' || _vm.order === undefined}})],2)])},staticRenderFns: [],
name: 'TableColumnSort',
extends: Column,
components: {
Arrow: Arrow,
ColumnHead: ColumnHead
},
computed: {
// an attribute set on the table wrapper
// because is to be used by all sort columns
sortedBy: function sortedBy () {
return this.$table.sortedBy
},
order: function order () {
return this.sortedBy[this.cell]
}
},
methods: {
emitSortEvent: function emitSortEvent (e) {
var sortedBy = getNewSortOrder(this.sortedBy, this.cell, e.shiftKey);
this.$table.$emit('update:sortedBy', sortedBy);
}
},
created: function created () {
this.$table = this.$parent;
if (!isObject(this.sortedBy)) {
warn("The VkTable 'sortedBy' prop is missing or not a valid object", this.$parent);
}
}
}
function getNewSortOrder (currentSort, by, multi) {
var sort = {};
var order = currentSort[by] === 'asc'
? 'desc'
: 'asc';
sort[by] = order;
return multi
? merge({}, currentSort, sort)
: sort
}
var Checkbox = {
functional: true,
props: ['checked'],
render: function render (h, ref) {
var data = ref.data;
var props = ref.props;
var listeners = ref.listeners;
var def = {
staticClass: 'uk-checkbox',
attrs: {
type: 'checkbox'
},
domProps: {
checked: props.checked
},
on: {
change: function (e) {
e.target.checked = props.checked;
}
}
};
return h('input', mergeData(data, def))
}
}
var select = {render: function(){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('column-head',{class:['vk-table-column-select', _vm.headClass],attrs:{"shrinked":""}},[(!_vm.$parent.singleSelectable)?_vm._t("head",[_c('span',{staticClass:"uk-form uk-text-center"},[_c('checkbox',{attrs:{"checked":_vm.$parent.allRowsSelected},on:{"click":_vm.$parent.toggleSelectionAll}})],1)]):_vm._e()],2)},staticRenderFns: [],
name: 'TableColumnSelect',
components: {
Checkbox: Checkbox,
ColumnHead: ColumnHead
},
props: {
headClass: {
type: String
},
cellClass: {
type: String
}
},
computed: {
$table: function $table () {
return this.$parent
}
},
cellRender: function (h, ref) {
var props = ref.props;
var data = ref.data;
var parent = ref.parent;
var row = props.row;
var cellClass = props.cellClass;
var scopedSlots = data.scopedSlots;
var cellSlot = scopedSlots.cell || (function (row) { return h('span', {
class: 'uk-form uk-text-center'
}, [
h(Checkbox, {
props: {
checked: parent.isSelected(row)
},
on: {
click: function (e) { return parent.toggleSelection(row); }
}
})
]); }
);
return h('td', {
class: ['uk-table-shrink', cellClass]
}, [
cellSlot(row)
])
}
}
var main = {
name: 'TableTree',
extends: Table,
props: {
expandedRows: {
type: Array,
default: function () { return []; }
},
childrenKey: {
type: String,
default: 'children'
}
},
computed: {
rows: function rows () {
var this$1 = this;
var rows = [];
var flatten = function (data, parent) {
if ( parent === void 0 ) parent = {};
var idCount = 1;
data.forEach(function (_row) {
var row = merge({}, _row);
var children = row[this$1.childrenKey];
var hasChildren = children && children.length;
row._vk_level = parent._vk_level !== undefined
? parent._vk_level + 1
: 0;
row._vk_id = row[this$1.rowKey]
? row[this$1.rowKey]
: row._vk_level === 0
? ("" + (idCount++))
: ((parent._vk_id) + "_" + (idCount++));
rows.push(row);
if (hasChildren && this$1.isExpanded(row)) {
flatten(children, row);
}
if (hasChildren) {
row._vk_childrenCount = children.length;
delete row[this$1.childrenKey];
}
});
};
flatten(this.data);
return rows
},
thereAreSubLevels: function thereAreSubLevels () {
return this.rows.some(function (row) { return row._vk_childrenCount; })
}
},
methods: {
isExpanded: function isExpanded (row) {
return includes(this.expandedRows, row._vk_id)
},
toggleExpand: function toggleExpand (row) {
var id = row._vk_id;
var expandedRows = [].concat( this.expandedRows );
var index = expandedRows.indexOf(id);
var isExpanded = index !== -1;
isExpanded
? expandedRows.splice(index, 1)
: expandedRows.push(id);
this.$emit('update:expandedRows', expandedRows);
}
}
}
var TreeArrow = {
functional: true,
props: ['rotated'],
render: function (h, ref) {
var data = ref.data;
var props = ref.props;
return h('span', mergeData(data, {
class: ['vk-table-column-tree__arrow', {
'vk-table-column-tree__arrow--rotated': props.rotated
}]
}));
}
}
var TreeIndent = {
functional: true,
render: function (h, ref) {
var data = ref.data;
var children = ref.children;
return h('span', mergeData(data, { class: 'vk-table-column-tree__indent' }), children);
}
}
var column = {
name: 'TableTreeColumn',
extends: Column,
cellRender: function (h, ref) {
var data = ref.data;
var props = ref.props;
var parent = ref.parent;
var row = props.row;
var cell = props.cell;
var cellClass = props.cellClass;
var scopedSlots = data.scopedSlots;
var cellValue = get(row, cell);
// support custom slots, fallback to default
var cellSlot = scopedSlots.cell || (function (cellValue, row) { return [
Array(row._vk_level).fill(h(TreeIndent)),
parent.thereAreSubLevels && h(TreeIndent, [
row._vk_childrenCount && h(TreeArrow, {
props: {
rotated: parent.isExpanded(row)
},
on: {
click: function (e) {
e._vk_row_click_prevented = true;
parent.toggleExpand(row);
}
}
})
]),
h('span', cellValue)
]; });
var def = {
class: cellClass
};
return h('td', def, cellSlot(cellValue, row))
}
}
export { Table, Column as TableColumn, sort as TableColumnSort, select as TableColumnSelect, main as TableTree, column as TableTreeColumn };