@vaadin/vaadin-grid
Advanced tools
@@ -18,3 +18,3 @@ { | ||
"name": "@vaadin/vaadin-grid", | ||
"version": "5.2.0-alpha1", | ||
"version": "5.2.0-alpha2", | ||
"main": "vaadin-grid.js", | ||
@@ -26,8 +26,14 @@ "author": "Vaadin Ltd", | ||
}, | ||
"files": [ | ||
"vaadin-*.js", | ||
"all-imports.js", | ||
"src", | ||
"theme" | ||
], | ||
"dependencies": { | ||
"@polymer/polymer": "^3.0.0", | ||
"@polymer/iron-resizable-behavior": "^3.0.0-pre.15", | ||
"@polymer/iron-scroll-target-behavior": "^3.0.0-pre.15", | ||
"@polymer/iron-a11y-keys-behavior": "^3.0.0-pre.15", | ||
"@polymer/iron-a11y-announcer": "^3.0.0-pre.15", | ||
"@polymer/iron-resizable-behavior": "^3.0.0-pre.18", | ||
"@polymer/iron-scroll-target-behavior": "^3.0.0-pre.18", | ||
"@polymer/iron-a11y-keys-behavior": "^3.0.0-pre.18", | ||
"@polymer/iron-a11y-announcer": "^3.0.0-pre.18", | ||
"@vaadin/vaadin-themable-mixin": "^1.2.1", | ||
@@ -45,20 +51,19 @@ "@vaadin/vaadin-checkbox": "^2.2.1", | ||
"supports-color": "3.1.2", | ||
"type-detect": "1.0.0", | ||
"@webcomponents/webcomponentsjs": "2.0.0-beta.2" | ||
"type-detect": "1.0.0" | ||
}, | ||
"devDependencies": { | ||
"@webcomponents/webcomponentsjs": "^2.0.0-beta.2", | ||
"wct-browser-legacy": "^0.0.1-pre.11", | ||
"@polymer/iron-test-helpers": "^3.0.0-pre.15", | ||
"@polymer/paper-input": "^3.0.0-pre.15", | ||
"@polymer/paper-checkbox": "^3.0.0-pre.15", | ||
"@polymer/iron-demo-helpers": "^3.0.0-pre.15", | ||
"@polymer/iron-flex-layout": "^3.0.0-pre.15", | ||
"@polymer/iron-image": "^3.0.0-pre.15", | ||
"@polymer/paper-slider": "^3.0.0-pre.15", | ||
"@polymer/iron-media-query": "^3.0.0-pre.15", | ||
"@polymer/iron-component-page": "^3.0.0-pre.15", | ||
"@polymer/iron-ajax": "^3.0.0-pre.15", | ||
"@polymer/app-localize-behavior": "^3.0.0-pre.15", | ||
"@polymer/iron-list": "^3.0.0-pre.15", | ||
"@webcomponents/webcomponentsjs": "^2.0.0", | ||
"wct-browser-legacy": "^1.0.1", | ||
"@polymer/iron-test-helpers": "^3.0.0-pre.18", | ||
"@polymer/paper-input": "^3.0.0-pre.18", | ||
"@polymer/paper-checkbox": "^3.0.0-pre.18", | ||
"@polymer/iron-demo-helpers": "^3.0.0-pre.18", | ||
"@polymer/iron-flex-layout": "^3.0.0-pre.18", | ||
"@polymer/iron-image": "^3.0.0-pre.18", | ||
"@polymer/paper-slider": "^3.0.0-pre.18", | ||
"@polymer/iron-media-query": "^3.0.0-pre.18", | ||
"@polymer/iron-component-page": "^3.0.0-pre.18", | ||
"@polymer/iron-ajax": "^3.0.0-pre.18", | ||
"@polymer/app-localize-behavior": "^3.0.0-pre.18", | ||
"@polymer/iron-list": "^3.0.0-pre.18", | ||
"@vaadin/vaadin-demo-helpers": "^2.0.2", | ||
@@ -65,0 +70,0 @@ "@vaadin/vaadin-button": "^2.1.0" |
@@ -25,3 +25,2 @@ [](https://badge.fury.io/js/%40vaadin%2Fvaadin-grid) | ||
<link rel="import" href="vaadin-grid-selection-column.html"> | ||
<link rel="import" href="vaadin-grid-sorter.html"> | ||
<next-code-block></next-code-block> | ||
@@ -33,34 +32,26 @@ </template> | ||
```html | ||
<dom-bind> | ||
<template> | ||
<iron-ajax auto url="https://demo.vaadin.com/demo-data/1.0/people?count=20" handle-as="json" last-response="{{users}}"></iron-ajax> | ||
<vaadin-grid theme="row-dividers" column-reordering-allowed multi-sort> | ||
<vaadin-grid theme="row-dividers" items="[[users.result]]" column-reordering-allowed multi-sort> | ||
<vaadin-grid-selection-column auto-select frozen> </vaadin-grid-selection-column> | ||
<vaadin-grid-selection-column auto-select frozen> </vaadin-grid-selection-column> | ||
<vaadin-grid-column width="9em" path="firstName"></vaadin-grid-column> | ||
<vaadin-grid-column width="9em"> | ||
<template class="header"> | ||
<vaadin-grid-sorter path="firstName">First Name</vaadin-grid-sorter> | ||
</template> | ||
<template>[[item.firstName]]</template> | ||
</vaadin-grid-column> | ||
<vaadin-grid-column width="9em" path="lastName"></vaadin-grid-column> | ||
<vaadin-grid-column width="9em"> | ||
<template class="header"> | ||
<vaadin-grid-sorter path="lastName">Last Name</vaadin-grid-sorter> | ||
</template> | ||
<template>[[item.lastName]]</template> | ||
</vaadin-grid-column> | ||
<vaadin-grid-column id="address-column" width="15em" flex-grow="2" path="address.street" label="Address"></vaadin-grid-column> | ||
<vaadin-grid-column width="15em" flex-grow="2"> | ||
<template class="header"> | ||
<vaadin-grid-sorter path="address.street">Address</vaadin-grid-sorter> | ||
</template> | ||
<template>[[item.address.street]], [[item.address.city]]</template> | ||
</vaadin-grid-column> | ||
</vaadin-grid> | ||
</vaadin-grid> | ||
</template> | ||
</dom-bind> | ||
<script> | ||
const grid = document.querySelector('vaadin-grid'); | ||
// Customize the "Address" column's renderer | ||
document.querySelector('#address-column').renderer = (root, grid, model) => { | ||
root.textContent = `${model.item.address.street}, ${model.item.address.city}`; | ||
}; | ||
// Populate the grid with data | ||
fetch('https://demo.vaadin.com/demo-data/1.0/people?count=200') | ||
.then(res => res.json()) | ||
.then(json => grid.items = json.result); | ||
</script> | ||
``` | ||
@@ -153,2 +144,7 @@ | ||
## Big Thanks | ||
Cross-browser Testing Platform and Open Source <3 Provided by [Sauce Labs](https://saucelabs.com). | ||
## Contributing | ||
@@ -155,0 +151,0 @@ |
@@ -17,3 +17,3 @@ /** | ||
_a11yGetHeaderRowCount(_columnTree) { | ||
return _columnTree.filter(level => level.some(col => col._headerTemplate || col.headerRenderer)).length; | ||
return _columnTree.filter(level => level.some(col => col._headerTemplate || col.headerRenderer || col.path || col.label)).length; | ||
} | ||
@@ -20,0 +20,0 @@ |
@@ -61,2 +61,16 @@ /** | ||
/** | ||
* Shown in the header cell of the column. | ||
*/ | ||
label: { | ||
type: String | ||
}, | ||
/** | ||
* Aligns the columns cell content horizontally to either start, center or end | ||
*/ | ||
textAlign: { | ||
type: String | ||
}, | ||
_lastFrozen: { | ||
@@ -104,2 +118,4 @@ type: Boolean, | ||
'_flexGrowChanged(flexGrow, _headerCell, _footerCell, _cells.*)', | ||
'_pathOrLabelChanged(path, label, _headerCell, _footerCell, _cells.*, renderer, headerRenderer, _bodyTemplate, _headerTemplate)', | ||
'_textAlignChanged(textAlign, _cells.*, _headerCell, _footerCell)', | ||
'_orderChanged(_order, _headerCell, _footerCell, _cells.*)', | ||
@@ -215,2 +231,19 @@ '_lastFrozenChanged(_lastFrozen)', | ||
_renderHeaderAndFooter() { | ||
if (this.headerRenderer) { | ||
this.__runRenderer(this.headerRenderer, this._headerCell); | ||
} | ||
if (this.footerRenderer) { | ||
this.__runRenderer(this.footerRenderer, this._footerCell); | ||
} | ||
} | ||
__runRenderer(renderer, cell, model) { | ||
const args = [cell._content, this]; | ||
if (model && model.item) { | ||
args.push(model); | ||
} | ||
renderer.apply(this, args); | ||
} | ||
__setColumnTemplateOrRenderer(template, renderer, cells) { | ||
@@ -228,3 +261,3 @@ if (template && renderer) { | ||
if (model.item || renderer === this.headerRenderer || renderer === this.footerRenderer) { | ||
renderer.call(this, cell._content, this, model); | ||
this.__runRenderer(renderer, cell, model); | ||
} | ||
@@ -323,2 +356,26 @@ } else if (cell._template !== template) { | ||
_pathOrLabelChanged(path, label, headerCell, footerCell, cells, renderer, headerRenderer, bodyTemplate, headerTemplate) { | ||
if (!headerRenderer && !headerTemplate && label !== undefined && headerCell) { | ||
headerCell._content.textContent = label; | ||
} | ||
if (path && cells.value) { | ||
if (!renderer && !bodyTemplate) { | ||
const pathRenderer = (root, owner, {item}) => root.textContent = this.get(path, item); | ||
cells.value.forEach(cell => cell._renderer = pathRenderer); | ||
this._grid._update(); | ||
} | ||
if (!headerRenderer && !headerTemplate && !label && headerCell) { | ||
const generatedLabel = path | ||
.substr(path.lastIndexOf('.') + 1) | ||
.replace(/([A-Z])/g, '-$1').toLowerCase() | ||
.replace(/-/, ' ') | ||
.replace(/\w\S*/g, str => str.charAt(0).toUpperCase() + str.substr(1)); | ||
headerCell._content.textContent = generatedLabel; | ||
headerCell.parentElement.hidden = false; | ||
} | ||
} | ||
} | ||
_toggleAttribute(name, bool, node) { | ||
@@ -361,2 +418,30 @@ if (node.hasAttribute(name) === !bool) { | ||
_textAlignChanged(textAlign, _cells, _headerCell, _footerCell) { | ||
if (textAlign === undefined) { | ||
return; | ||
} | ||
let textAlignFallback; | ||
if (getComputedStyle(this._grid).direction === 'ltr') { | ||
if (textAlign === 'start') { | ||
textAlignFallback = 'left'; | ||
} else if (textAlign === 'end') { | ||
textAlignFallback = 'right'; | ||
} | ||
} else { | ||
if (textAlign === 'start') { | ||
textAlignFallback = 'right'; | ||
} else if (textAlign === 'end') { | ||
textAlignFallback = 'left'; | ||
} | ||
} | ||
this._allCells.forEach(cell => { | ||
cell._content.style.textAlign = textAlign; | ||
if (getComputedStyle(cell._content).textAlign !== textAlign) { | ||
cell._content.style.textAlign = textAlignFallback; | ||
} | ||
}); | ||
} | ||
_hiddenChanged(hidden, headerCell, footerCell, cells) { | ||
@@ -380,14 +465,6 @@ if (this.parentElement && this.parentElement._columnPropChanged) { | ||
* A `<vaadin-grid-column>` is used to configure how a column in `<vaadin-grid>` | ||
* should look like by using HTML templates. | ||
* A column can have a template for each of the three table sections: header, body and footer. | ||
* should look like. | ||
* | ||
* The `class` attribute is used to differentiate header and footer templates from the body template. | ||
* | ||
* #### Example: | ||
* ```html | ||
* <vaadin-grid-column> | ||
* <template class="header">I'm in the header</template> | ||
* <template>I'm in the body</template> | ||
* <template class="footer">I'm in the footer</template> | ||
* </vaadin-grid-column> | ||
* See `<vaadin-grid>` documentation and demos for instructions and examples on how | ||
* to configure the `<vaadin-grid-column>`. | ||
* ``` | ||
@@ -437,2 +514,10 @@ * | ||
/** | ||
* Path to an item sub-property whose value gets displayed in the column body cells. | ||
* The property name is also shown in the column header if an explicit label/renderer isn't defined. | ||
*/ | ||
path: { | ||
type: String | ||
}, | ||
_bodyTemplate: { | ||
@@ -439,0 +524,0 @@ type: Object |
@@ -52,3 +52,3 @@ /** | ||
return [ | ||
'_detailsOpenedItemsChanged(detailsOpenedItems.*, dataProvider, _physicalCountVal, _rowDetailsTemplate, rowDetailsRenderer)', | ||
'_detailsOpenedItemsChanged(detailsOpenedItems.*, _rowDetailsTemplate, rowDetailsRenderer)', | ||
'_rowDetailsTemplateOrRendererChanged(_rowDetailsTemplate, rowDetailsRenderer)' | ||
@@ -59,4 +59,7 @@ ]; | ||
_rowDetailsTemplateOrRendererChanged(rowDetailsTemplate, rowDetailsRenderer) { | ||
if (rowDetailsTemplate && rowDetailsRenderer) { | ||
throw new Error('You should only use either a renderer or a template for row details'); | ||
} | ||
if (rowDetailsTemplate || rowDetailsRenderer) { | ||
if (rowDetailsTemplate) { | ||
if (rowDetailsTemplate && !rowDetailsTemplate.templatizer) { | ||
var templatizer = new Templatizer(); | ||
@@ -72,5 +75,6 @@ templatizer._grid = this; | ||
Array.from(this.$.items.children).forEach(row => { | ||
// TODO: Only update if there's no details cell | ||
// Ensure the rows have a row details cell | ||
this._updateRow(row, this._columnTree[this._columnTree.length - 1]); | ||
if (!row.querySelector('[part~=details-cell]')) { | ||
this._updateRow(row, this._columnTree[this._columnTree.length - 1]); | ||
this._a11yUpdateRowDetailsOpened(row, false); | ||
} | ||
// Clear any old template instances | ||
@@ -81,28 +85,18 @@ delete row.querySelector('[part~=details-cell]')._instance; | ||
this._update(); | ||
if (this.detailsOpenedItems.length) { | ||
Array.from(this.$.items.children).forEach(this._toggleDetailsCell, this); | ||
this._update(); | ||
} | ||
} | ||
} | ||
_detailsOpenedItemsChanged(changeRecord, dataProvider, physicalCount, rowDetailsTemplate, rowDetailsRenderer) { | ||
if (rowDetailsTemplate && rowDetailsRenderer) { | ||
throw new Error('You should only use either a renderer or a template for row details'); | ||
} | ||
if (dataProvider === undefined || !rowDetailsTemplate && !rowDetailsRenderer) { | ||
return; | ||
} | ||
if (changeRecord.path === 'detailsOpenedItems.length') { | ||
_detailsOpenedItemsChanged(changeRecord, rowDetailsTemplate, rowDetailsRenderer) { | ||
if (changeRecord.path === 'detailsOpenedItems.length' || !changeRecord.value) { | ||
// Let’s avoid duplicate work of both “.splices” and “.length” updates. | ||
return; | ||
} | ||
this._flushItemsDebouncer(); | ||
if (this._lastDetailsOpenedItems && physicalCount) { | ||
this._physicalItems.forEach(this._toggleDetailsCell, this); | ||
this._render(); | ||
} | ||
this._lastDetailsOpenedItems = this.detailsOpenedItems; | ||
Array.from(this.$.items.children).forEach(row => { | ||
this._toggleDetailsCell(row, row._item); | ||
this._a11yUpdateRowDetailsOpened(row, this._isDetailsOpened(row._item)); | ||
}); | ||
} | ||
@@ -128,4 +122,3 @@ | ||
cell._renderer.call(this, cell._content, this, {index: row.index, item: item}); | ||
this._updateItem(row, item); | ||
} else if (!cell._instance) { | ||
} else if (this._rowDetailsTemplate && !cell._instance) { | ||
// Stamp the template | ||
@@ -142,2 +135,4 @@ cell._instance = this._rowDetailsTemplate.templatizer.createInstance(); | ||
} | ||
this._updateMetrics(); | ||
this._positionItems(); | ||
} | ||
@@ -144,0 +139,0 @@ |
@@ -25,4 +25,6 @@ /** | ||
return { | ||
size: Number, | ||
size: { | ||
type: Number, | ||
notify: true | ||
}, | ||
_vidxOffset: { | ||
@@ -29,0 +31,0 @@ value: 0 |
@@ -74,8 +74,7 @@ /** | ||
} else { | ||
this._sorters.forEach(sorter => { | ||
sorter._order = null; | ||
sorter.direction = null; | ||
}); | ||
if (sorter.direction) { | ||
this._sorters.forEach(sorter => { | ||
sorter._order = null; | ||
sorter.direction = null; | ||
}); | ||
this._sorters = [sorter]; | ||
@@ -82,0 +81,0 @@ } |
@@ -13,3 +13,2 @@ /** | ||
const $_documentContainer = document.createElement('template'); | ||
$_documentContainer.setAttribute('style', 'display: none;'); | ||
@@ -16,0 +15,0 @@ $_documentContainer.innerHTML = `<custom-style> |
const $_documentContainer = document.createElement('template'); | ||
$_documentContainer.setAttribute('style', 'display: none;'); | ||
@@ -4,0 +3,0 @@ $_documentContainer.innerHTML = `<dom-module id="vaadin-grid-styles"> |
@@ -14,3 +14,2 @@ /** | ||
const $_documentContainer = document.createElement('template'); | ||
$_documentContainer.setAttribute('style', 'display: none;'); | ||
@@ -17,0 +16,0 @@ $_documentContainer.innerHTML = `<custom-style> |
@@ -43,3 +43,3 @@ /** | ||
* | ||
* `<vaadin-grid>` is a free, high quality data grid / data table Polymer element. The content of the | ||
* `<vaadin-grid>` is a free, high quality data grid / data table Web Component. The content of the | ||
* the grid can be populated in two ways: imperatively by using renderer callback function and | ||
@@ -52,4 +52,15 @@ * declaratively by using Polymer's Templates. | ||
* | ||
* Use the [`<vaadin-grid-column>`](#/elements/vaadin-grid-column) element to configure the grid columns. | ||
* `vaadin-grid-column` element provides you with three types of `renderer` callback functions: `headerRenderer`, | ||
* Use the [`<vaadin-grid-column>`](#/elements/vaadin-grid-column) element to configure the grid columns. Set `path` and `label` | ||
* shorthand properties for the columns to define what gets rendered in the cells of the column. | ||
* | ||
* #### Example: | ||
* ```html | ||
* <vaadin-grid> | ||
* <vaadin-grid-column path="name.first" label="First Name"></vaadin-grid-column> | ||
* <vaadin-grid-column path="name.last" label="Last Name"></vaadin-grid-column> | ||
* <vaadin-grid-column path="email"></vaadin-grid-column> | ||
* </vaadin-grid> | ||
* ``` | ||
* | ||
* For custom content `vaadin-grid-column` element provides you with three types of `renderer` callback functions: `headerRenderer`, | ||
* `renderer` and `footerRenderer`. | ||
@@ -298,3 +309,3 @@ * | ||
static get version() { | ||
return '5.2.0-alpha1'; | ||
return '5.2.0-alpha2'; | ||
} | ||
@@ -575,3 +586,2 @@ | ||
this._a11yUpdateRowDetailsOpened(row, model.detailsOpened); | ||
this._toggleAttribute('selected', model.selected, row); | ||
@@ -659,2 +669,18 @@ this._a11yUpdateRowSelected(row, model.selected); | ||
} | ||
/** | ||
* Manually invoke existing renderers for all the columns | ||
* (header, footer and body cells) and opened row details. | ||
*/ | ||
render() { | ||
if (this._columnTree) { | ||
// header and footer renderers | ||
this._columnTree.forEach(level => { | ||
level.forEach(column => column._renderHeaderAndFooter()); | ||
}); | ||
// body and row details renderers | ||
this._update(); | ||
} | ||
} | ||
} | ||
@@ -661,0 +687,0 @@ |
import '@vaadin/vaadin-lumo-styles/color.js'; | ||
const $_documentContainer = document.createElement('template'); | ||
$_documentContainer.setAttribute('style', 'display: none;'); | ||
@@ -5,0 +4,0 @@ $_documentContainer.innerHTML = `<dom-module id="lumo-grid-sorter" theme-for="vaadin-grid-sorter"> |
@@ -9,3 +9,2 @@ import '@vaadin/vaadin-lumo-styles/color.js'; | ||
const $_documentContainer = document.createElement('template'); | ||
$_documentContainer.setAttribute('style', 'display: none;'); | ||
@@ -12,0 +11,0 @@ $_documentContainer.innerHTML = `<dom-module id="lumo-grid" theme-for="vaadin-grid"> |
import '@vaadin/vaadin-lumo-styles/color.js'; | ||
import '@vaadin/vaadin-lumo-styles/spacing.js'; | ||
const $_documentContainer = document.createElement('template'); | ||
$_documentContainer.setAttribute('style', 'display: none;'); | ||
@@ -6,0 +5,0 @@ $_documentContainer.innerHTML = `<dom-module id="lumo-grid-tree-toggle" theme-for="vaadin-grid-tree-toggle"> |
import '@vaadin/vaadin-material-styles/color.js'; | ||
import '@vaadin/vaadin-material-styles/font-icons.js'; | ||
const $_documentContainer = document.createElement('template'); | ||
$_documentContainer.setAttribute('style', 'display: none;'); | ||
@@ -6,0 +5,0 @@ $_documentContainer.innerHTML = `<dom-module id="material-grid-sorter" theme-for="vaadin-grid-sorter"> |
import '@vaadin/vaadin-material-styles/color.js'; | ||
import '@vaadin/vaadin-material-styles/typography.js'; | ||
const $_documentContainer = document.createElement('template'); | ||
$_documentContainer.setAttribute('style', 'display: none;'); | ||
@@ -6,0 +5,0 @@ $_documentContainer.innerHTML = `<dom-module id="material-grid" theme-for="vaadin-grid"> |
@@ -5,3 +5,2 @@ import '@vaadin/vaadin-material-styles/color.js'; | ||
const $_documentContainer = document.createElement('template'); | ||
$_documentContainer.setAttribute('style', 'display: none;'); | ||
@@ -8,0 +7,0 @@ $_documentContainer.innerHTML = `<dom-module id="material-grid-tree-toggle" theme-for="vaadin-grid-tree-toggle"> |
243726
-83.23%59
-61.44%6402
-53.77%157
-2.48%