Add cellHeight option, increase padding to spacer-2

This commit is contained in:
Faris Ansari 2018-02-21 12:26:45 +05:30
parent a810c011ef
commit 62203c79bb
8 changed files with 483 additions and 363 deletions

View File

@ -315,6 +315,20 @@ function promisify(fn, context = null) {
}; };
} }
function linkProperties(target, source, properties) {
const props = properties.reduce((acc, prop) => {
acc[prop] = {
get() {
return source[prop];
}
};
return acc;
}, {});
Object.defineProperties(target, props);
}
class DataManager { class DataManager {
constructor(options) { constructor(options) {
this.options = options; this.options = options;
@ -406,6 +420,7 @@ class DataManager {
resizable: true, resizable: true,
focusable: true, focusable: true,
dropdown: true, dropdown: true,
width: null,
format: (value) => { format: (value) => {
if (value === null || value === undefined) { if (value === null || value === undefined) {
return ''; return '';
@ -429,8 +444,7 @@ class DataManager {
align: 'left', align: 'left',
sortOrder: 'none', sortOrder: 'none',
colIndex: i, colIndex: i,
column: this.columns[i], column: this.columns[i]
width: 0
}; };
if (content !== null && typeof content === 'object') { if (content !== null && typeof content === 'object') {
@ -475,6 +489,10 @@ class DataManager {
} }
row = row.concat(d); row = row.concat(d);
while (row.length < this.columns.length) {
row.push('');
}
} else { } else {
// row is a dict // row is a dict
for (let col of this.columns) { for (let col of this.columns) {
@ -795,14 +813,17 @@ class DataError extends TypeError {}
class ColumnManager { class ColumnManager {
constructor(instance) { constructor(instance) {
this.instance = instance; this.instance = instance;
this.options = this.instance.options;
this.fireEvent = this.instance.fireEvent; linkProperties(this, this.instance, [
this.header = this.instance.header; 'options',
this.datamanager = this.instance.datamanager; 'fireEvent',
this.style = this.instance.style; 'header',
this.wrapper = this.instance.wrapper; 'datamanager',
this.rowmanager = this.instance.rowmanager; 'style',
this.bodyScrollable = this.instance.bodyScrollable; 'wrapper',
'rowmanager',
'bodyScrollable'
]);
this.bindEvents(); this.bindEvents();
getDropdownHTML = getDropdownHTML.bind(this, this.options.dropdownButton); getDropdownHTML = getDropdownHTML.bind(this, this.options.dropdownButton);
@ -916,7 +937,7 @@ class ColumnManager {
const { colIndex } = $.data($resizingCell); const { colIndex } = $.data($resizingCell);
this.setColumnWidth(colIndex); this.setColumnWidth(colIndex);
this.instance.setBodyWidth(); this.style.setBodyStyle();
$resizingCell = null; $resizingCell = null;
}); });
@ -1052,133 +1073,6 @@ class ColumnManager {
}); });
} }
setDimensions() {
this.setHeaderStyle();
this.setupMinWidth();
this.setupNaturalColumnWidth();
this.distributeRemainingWidth();
this.setColumnStyle();
this.setDefaultCellHeight();
}
setHeaderStyle() {
if (!this.options.takeAvailableSpace) {
// setting width as 0 will ensure that the
// header doesn't take the available space
$.style(this.header, {
width: 0
});
}
$.style(this.header, {
margin: 0
});
// don't show resize cursor on nonResizable columns
const nonResizableColumnsSelector = this.datamanager.getColumns()
.filter(col => col.resizable === false)
.map(col => col.colIndex)
.map(i => `.data-table-header [data-col-index="${i}"]`)
.join();
this.style.setStyle(nonResizableColumnsSelector, {
cursor: 'pointer'
});
}
setupMinWidth() {
$.each('.data-table-col', this.header).map(col => {
const width = $.style($('.content', col), 'width');
const { colIndex } = $.data(col);
const column = this.getColumn(colIndex);
if (!column.minWidth) {
// only set this once
this.datamanager.updateColumn(colIndex, { minWidth: width });
}
});
}
setupNaturalColumnWidth() {
// set initial width as naturally calculated by table's first row
$.each('.data-table-row[data-row-index="0"] .data-table-col', this.bodyScrollable).map($cell => {
const { colIndex } = $.data($cell);
if (this.getColumn(colIndex).width > 0) {
// already set
return;
}
let width = $.style($('.content', $cell), 'width');
const minWidth = this.getColumnMinWidth(colIndex);
if (width < minWidth) {
width = minWidth;
}
this.datamanager.updateColumn(colIndex, { width });
});
}
distributeRemainingWidth() {
if (!this.options.takeAvailableSpace) return;
const wrapperWidth = $.style(this.instance.datatableWrapper, 'width');
const headerWidth = $.style(this.header, 'width');
if (headerWidth >= wrapperWidth) {
// don't resize, horizontal scroll takes place
return;
}
const resizableColumns = this.datamanager.getColumns().filter(
col => col.resizable === undefined || col.resizable
);
const deltaWidth = (wrapperWidth - headerWidth) / resizableColumns.length;
resizableColumns.map(col => {
const width = $.style(this.getColumnHeaderElement(col.colIndex), 'width');
let finalWidth = Math.min(width + deltaWidth) - 2;
this.datamanager.updateColumn(col.colIndex, { width: finalWidth });
});
}
setDefaultCellHeight() {
if (this.__cellHeightSet) return;
const height = $.style($('.data-table-col', this.instance.datatableWrapper), 'height');
if (height) {
this.setCellHeight(height);
this.__cellHeightSet = true;
}
}
setCellHeight(height) {
this.style.setStyle('.data-table-col .content', {
height: height + 'px'
});
this.style.setStyle('.data-table-col .edit-cell', {
height: height + 'px'
});
}
setColumnStyle() {
// align columns
this.getColumns()
.map(column => {
// alignment
if (['left', 'center', 'right'].includes(column.align)) {
this.style.setStyle(`[data-col-index="${column.colIndex}"]`, {
'text-align': column.align
});
}
// width
this.setColumnHeaderWidth(column.colIndex);
this.setColumnWidth(column.colIndex);
});
this.instance.setBodyWidth();
}
sortRows(colIndex, sortOrder) { sortRows(colIndex, sortOrder) {
return this.datamanager.sortRows(colIndex, sortOrder); return this.datamanager.sortRows(colIndex, sortOrder);
} }
@ -1247,12 +1141,6 @@ class ColumnManager {
return this.datamanager.getColumnCount() - 1; return this.datamanager.getColumnCount() - 1;
} }
getColumnHeaderElement(colIndex) {
colIndex = +colIndex;
if (colIndex < 0) return null;
return $(`.data-table-col[data-is-header][data-col-index="${colIndex}"]`, this.wrapper);
}
getSerialColumnIndex() { getSerialColumnIndex() {
const columns = this.datamanager.getColumns(); const columns = this.datamanager.getColumns();
@ -1326,7 +1214,7 @@ class CellManager {
let $cell = this.$focusedCell; let $cell = this.$focusedCell;
if (direction === 'left') { if (direction === 'left' || direction === 'shift+tab') {
$cell = this.getLeftCell$($cell); $cell = this.getLeftCell$($cell);
} else if (direction === 'right' || direction === 'tab') { } else if (direction === 'right' || direction === 'tab') {
$cell = this.getRightCell$($cell); $cell = this.getRightCell$($cell);
@ -1362,7 +1250,7 @@ class CellManager {
return true; return true;
}; };
['left', 'right', 'up', 'down', 'tab'].map( ['left', 'right', 'up', 'down', 'tab', 'shift+tab'].map(
direction => this.keyboard.on(direction, () => focusCell(direction)) direction => this.keyboard.on(direction, () => focusCell(direction))
); );
@ -2114,7 +2002,7 @@ class BodyRenderer {
} }
}, },
/* eslint-disable */ /* eslint-disable */
no_data_text: this.options.loadingText, no_data_text: this.options.noDataMessage,
no_data_class: 'empty-state' no_data_class: 'empty-state'
/* eslint-enable */ /* eslint-enable */
}); });
@ -2154,16 +2042,33 @@ function getBodyHTML(rows) {
} }
class Style { class Style {
constructor(instance) {
this.instance = instance;
constructor(datatable) { linkProperties(this, this.instance, [
this.datatable = datatable; 'options', 'datamanager', 'columnmanager',
this.scopeClass = 'datatable-instance-' + datatable.constructor.instances; 'header', 'bodyScrollable', 'getColumn'
datatable.datatableWrapper.classList.add(this.scopeClass); ]);
this.scopeClass = 'datatable-instance-' + instance.constructor.instances;
instance.datatableWrapper.classList.add(this.scopeClass);
const styleEl = document.createElement('style'); const styleEl = document.createElement('style');
datatable.wrapper.insertBefore(styleEl, datatable.datatableWrapper); instance.wrapper.insertBefore(styleEl, instance.datatableWrapper);
this.styleEl = styleEl; this.styleEl = styleEl;
this.styleSheet = styleEl.sheet; this.styleSheet = styleEl.sheet;
this.bindResizeWindow();
}
bindResizeWindow() {
if (this.options.layout === 'fluid') {
$.on(window, 'resize', throttle(() => {
this.distributeRemainingWidth();
this.refreshColumnWidth();
this.setBodyStyle();
}, 300));
}
} }
destroy() { destroy() {
@ -2190,6 +2095,169 @@ class Style {
this.styleSheet.insertRule(ruleString, _index); this.styleSheet.insertRule(ruleString, _index);
return _index; return _index;
} }
setDimensions() {
this.setHeaderStyle();
this.setupMinWidth();
this.setupNaturalColumnWidth();
this.setupColumnWidth();
this.distributeRemainingWidth();
this.setColumnStyle();
this.setDefaultCellHeight();
this.setBodyStyle();
}
setHeaderStyle() {
if (this.options.layout === 'fluid') {
// setting width as 0 will ensure that the
// header doesn't take the available space
$.style(this.header, {
width: 0
});
}
$.style(this.header, {
margin: 0
});
// don't show resize cursor on nonResizable columns
const nonResizableColumnsSelector = this.datamanager.getColumns()
.filter(col => col.resizable === false)
.map(col => col.colIndex)
.map(i => `.data-table-header [data-col-index="${i}"]`)
.join();
this.setStyle(nonResizableColumnsSelector, {
cursor: 'pointer'
});
}
setupMinWidth() {
$.each('.data-table-col', this.header).map(col => {
const width = $.style($('.content', col), 'width');
const {
colIndex
} = $.data(col);
const column = this.getColumn(colIndex);
if (!column.minWidth) {
// only set this once
column.minWidth = width;
}
});
}
setupNaturalColumnWidth() {
if (!$('.data-table-row')) return;
// set initial width as naturally calculated by table's first row
$.each('.data-table-row[data-row-index="0"] .data-table-col', this.bodyScrollable).map($cell => {
const {
colIndex
} = $.data($cell);
const column = this.datamanager.getColumn(colIndex);
let naturalWidth = $.style($('.content', $cell), 'width');
column.naturalWidth = naturalWidth;
});
}
setupColumnWidth() {
this.datamanager.getColumns()
.map(column => {
if (column.width === null) {
column.width = column.naturalWidth;
}
if (column.width < column.minWidth) {
column.width = column.minWidth;
}
});
}
distributeRemainingWidth() {
if (this.options.layout !== 'fluid') return;
const wrapperWidth = $.style(this.instance.datatableWrapper, 'width');
const headerWidth = $.style(this.header, 'width');
const resizableColumns = this.datamanager.getColumns().filter(col => col.resizable);
const deltaWidth = (wrapperWidth - headerWidth) / resizableColumns.length;
resizableColumns.map(col => {
const width = $.style(this.getColumnHeaderElement(col.colIndex), 'width');
let finalWidth = Math.floor(width + deltaWidth) - 2;
this.datamanager.updateColumn(col.colIndex, {
width: finalWidth
});
});
}
setDefaultCellHeight() {
if (this.__cellHeightSet) return;
const height = this.options.cellHeight || $.style($('.data-table-col', this.instance.datatableWrapper), 'height');
if (height) {
this.setCellHeight(height);
this.__cellHeightSet = true;
}
}
setCellHeight(height) {
this.setStyle('.data-table-col .content', {
height: height + 'px'
});
this.setStyle('.data-table-col .edit-cell', {
height: height + 'px'
});
}
setColumnStyle() {
// align columns
this.datamanager.getColumns()
.map(column => {
// alignment
if (['left', 'center', 'right'].includes(column.align)) {
this.setStyle(`[data-col-index="${column.colIndex}"]`, {
'text-align': column.align
});
}
// width
this.columnmanager.setColumnHeaderWidth(column.colIndex);
this.columnmanager.setColumnWidth(column.colIndex);
});
this.setBodyStyle();
}
refreshColumnWidth() {
this.datamanager.getColumns()
.map(column => {
this.columnmanager.setColumnHeaderWidth(column.colIndex);
this.columnmanager.setColumnWidth(column.colIndex);
});
}
setBodyStyle() {
const width = $.style(this.header, 'width');
$.style(this.bodyScrollable, {
width: width + 'px'
});
$.style(this.bodyScrollable, {
marginTop: $.style(this.header, 'height') + 'px'
});
$.style($('table', this.bodyScrollable), {
margin: 0
});
}
getColumnHeaderElement(colIndex) {
colIndex = +colIndex;
if (colIndex < 0) return null;
return $(`.data-table-col[data-col-index="${colIndex}"]`, this.header);
}
} }
const KEYCODES = { const KEYCODES = {
@ -2292,8 +2360,9 @@ var DEFAULT_OPTIONS = {
addCheckboxColumn: false, addCheckboxColumn: false,
enableClusterize: true, enableClusterize: true,
enableLogs: false, enableLogs: false,
takeAvailableSpace: false, layout: 'fixed', // fixed, fluid
loadingText: '' noDataMessage: 'No Data',
cellHeight: null
}; };
class DataTable { class DataTable {
@ -2394,29 +2463,21 @@ class DataTable {
} }
setDimensions() { setDimensions() {
this.columnmanager.setDimensions(); this.style.setDimensions();
this.setBodyWidth();
$.style(this.bodyScrollable, {
marginTop: $.style(this.header, 'height') + 'px'
});
$.style($('table', this.bodyScrollable), {
margin: 0
});
}
setBodyWidth() {
const width = $.style(this.header, 'width');
$.style(this.bodyScrollable, { width: width + 'px' });
} }
getColumn(colIndex) { getColumn(colIndex) {
return this.datamanager.getColumn(colIndex); return this.datamanager.getColumn(colIndex);
} }
getColumns() {
return this.datamanager.getColumns();
}
getRows() {
return this.datamanager.getRows();
}
getCell(colIndex, rowIndex) { getCell(colIndex, rowIndex) {
return this.datamanager.getCell(colIndex, rowIndex); return this.datamanager.getCell(colIndex, rowIndex);
} }
@ -2471,13 +2532,13 @@ class DataTable {
DataTable.instances = 0; DataTable.instances = 0;
var name = "frappe-datatable"; var name = "frappe-datatable";
var version = "0.0.1"; var version = "0.0.2";
var description = "A modern datatable library for the web"; var description = "A modern datatable library for the web";
var main = "dist/frappe-datatable.cjs.js"; var main = "dist/frappe-datatable.cjs.js";
var scripts = {"start":"npm run dev","build":"rollup -c","dev":"rollup -c -w","test":"mocha --compilers js:babel-core/register --colors ./test/*.spec.js","test:watch":"mocha --compilers js:babel-core/register --colors -w ./test/*.spec.js"}; var scripts = {"start":"npm run dev","build":"rollup -c","dev":"rollup -c -w","test":"mocha --compilers js:babel-core/register --colors ./test/*.spec.js","test:watch":"mocha --compilers js:babel-core/register --colors -w ./test/*.spec.js"};
var devDependencies = {"chai":"3.5.0","cssnano":"^3.10.0","deepmerge":"^2.0.1","eslint":"3.19.0","eslint-loader":"1.7.1","mocha":"3.3.0","postcss-cssnext":"^3.1.0","postcss-nested":"^3.0.0","precss":"^3.1.0","rollup-plugin-json":"^2.3.0","rollup-plugin-postcss":"^1.2.8","rollup-plugin-uglify":"^3.0.0"}; var devDependencies = {"chai":"3.5.0","cssnano":"^3.10.0","deepmerge":"^2.0.1","eslint":"3.19.0","eslint-loader":"1.7.1","mocha":"3.3.0","postcss-cssnext":"^3.1.0","postcss-nested":"^3.0.0","precss":"^3.1.0","rollup-plugin-json":"^2.3.0","rollup-plugin-postcss":"^1.2.8","rollup-plugin-uglify":"^3.0.0"};
var repository = {"type":"git","url":"https://github.com/frappe/datatable.git"}; var repository = {"type":"git","url":"https://github.com/frappe/datatable.git"};
var keywords = ["webpack","es6","starter","library","universal","umd","commonjs"]; var keywords = ["datatable","data","grid","table"];
var author = "Faris Ansari"; var author = "Faris Ansari";
var license = "MIT"; var license = "MIT";
var bugs = {"url":"https://github.com/frappe/datatable/issues"}; var bugs = {"url":"https://github.com/frappe/datatable/issues"};

View File

@ -182,8 +182,8 @@
} }
.data-table-col .content { .data-table-col .content {
padding: 4px; padding: 8px;
padding: 0.25rem; padding: 0.5rem;
border: 2px solid transparent; border: 2px solid transparent;
} }
@ -196,8 +196,8 @@
.data-table-col .edit-cell { .data-table-col .edit-cell {
display: none; display: none;
// position: absolute; // position: absolute;
padding: 4px; padding: 8px;
padding: 0.25rem; padding: 0.5rem;
background: #fff; background: #fff;
z-index: 1; z-index: 1;
height: 100%; height: 100%;

View File

@ -314,6 +314,20 @@ function promisify(fn, context = null) {
}; };
} }
function linkProperties(target, source, properties) {
const props = properties.reduce((acc, prop) => {
acc[prop] = {
get() {
return source[prop];
}
};
return acc;
}, {});
Object.defineProperties(target, props);
}
class DataManager { class DataManager {
constructor(options) { constructor(options) {
this.options = options; this.options = options;
@ -405,6 +419,7 @@ class DataManager {
resizable: true, resizable: true,
focusable: true, focusable: true,
dropdown: true, dropdown: true,
width: null,
format: (value) => { format: (value) => {
if (value === null || value === undefined) { if (value === null || value === undefined) {
return ''; return '';
@ -428,8 +443,7 @@ class DataManager {
align: 'left', align: 'left',
sortOrder: 'none', sortOrder: 'none',
colIndex: i, colIndex: i,
column: this.columns[i], column: this.columns[i]
width: 0
}; };
if (content !== null && typeof content === 'object') { if (content !== null && typeof content === 'object') {
@ -474,6 +488,10 @@ class DataManager {
} }
row = row.concat(d); row = row.concat(d);
while (row.length < this.columns.length) {
row.push('');
}
} else { } else {
// row is a dict // row is a dict
for (let col of this.columns) { for (let col of this.columns) {
@ -794,14 +812,17 @@ class DataError extends TypeError {}
class ColumnManager { class ColumnManager {
constructor(instance) { constructor(instance) {
this.instance = instance; this.instance = instance;
this.options = this.instance.options;
this.fireEvent = this.instance.fireEvent; linkProperties(this, this.instance, [
this.header = this.instance.header; 'options',
this.datamanager = this.instance.datamanager; 'fireEvent',
this.style = this.instance.style; 'header',
this.wrapper = this.instance.wrapper; 'datamanager',
this.rowmanager = this.instance.rowmanager; 'style',
this.bodyScrollable = this.instance.bodyScrollable; 'wrapper',
'rowmanager',
'bodyScrollable'
]);
this.bindEvents(); this.bindEvents();
getDropdownHTML = getDropdownHTML.bind(this, this.options.dropdownButton); getDropdownHTML = getDropdownHTML.bind(this, this.options.dropdownButton);
@ -915,7 +936,7 @@ class ColumnManager {
const { colIndex } = $.data($resizingCell); const { colIndex } = $.data($resizingCell);
this.setColumnWidth(colIndex); this.setColumnWidth(colIndex);
this.instance.setBodyWidth(); this.style.setBodyStyle();
$resizingCell = null; $resizingCell = null;
}); });
@ -1051,133 +1072,6 @@ class ColumnManager {
}); });
} }
setDimensions() {
this.setHeaderStyle();
this.setupMinWidth();
this.setupNaturalColumnWidth();
this.distributeRemainingWidth();
this.setColumnStyle();
this.setDefaultCellHeight();
}
setHeaderStyle() {
if (!this.options.takeAvailableSpace) {
// setting width as 0 will ensure that the
// header doesn't take the available space
$.style(this.header, {
width: 0
});
}
$.style(this.header, {
margin: 0
});
// don't show resize cursor on nonResizable columns
const nonResizableColumnsSelector = this.datamanager.getColumns()
.filter(col => col.resizable === false)
.map(col => col.colIndex)
.map(i => `.data-table-header [data-col-index="${i}"]`)
.join();
this.style.setStyle(nonResizableColumnsSelector, {
cursor: 'pointer'
});
}
setupMinWidth() {
$.each('.data-table-col', this.header).map(col => {
const width = $.style($('.content', col), 'width');
const { colIndex } = $.data(col);
const column = this.getColumn(colIndex);
if (!column.minWidth) {
// only set this once
this.datamanager.updateColumn(colIndex, { minWidth: width });
}
});
}
setupNaturalColumnWidth() {
// set initial width as naturally calculated by table's first row
$.each('.data-table-row[data-row-index="0"] .data-table-col', this.bodyScrollable).map($cell => {
const { colIndex } = $.data($cell);
if (this.getColumn(colIndex).width > 0) {
// already set
return;
}
let width = $.style($('.content', $cell), 'width');
const minWidth = this.getColumnMinWidth(colIndex);
if (width < minWidth) {
width = minWidth;
}
this.datamanager.updateColumn(colIndex, { width });
});
}
distributeRemainingWidth() {
if (!this.options.takeAvailableSpace) return;
const wrapperWidth = $.style(this.instance.datatableWrapper, 'width');
const headerWidth = $.style(this.header, 'width');
if (headerWidth >= wrapperWidth) {
// don't resize, horizontal scroll takes place
return;
}
const resizableColumns = this.datamanager.getColumns().filter(
col => col.resizable === undefined || col.resizable
);
const deltaWidth = (wrapperWidth - headerWidth) / resizableColumns.length;
resizableColumns.map(col => {
const width = $.style(this.getColumnHeaderElement(col.colIndex), 'width');
let finalWidth = Math.min(width + deltaWidth) - 2;
this.datamanager.updateColumn(col.colIndex, { width: finalWidth });
});
}
setDefaultCellHeight() {
if (this.__cellHeightSet) return;
const height = $.style($('.data-table-col', this.instance.datatableWrapper), 'height');
if (height) {
this.setCellHeight(height);
this.__cellHeightSet = true;
}
}
setCellHeight(height) {
this.style.setStyle('.data-table-col .content', {
height: height + 'px'
});
this.style.setStyle('.data-table-col .edit-cell', {
height: height + 'px'
});
}
setColumnStyle() {
// align columns
this.getColumns()
.map(column => {
// alignment
if (['left', 'center', 'right'].includes(column.align)) {
this.style.setStyle(`[data-col-index="${column.colIndex}"]`, {
'text-align': column.align
});
}
// width
this.setColumnHeaderWidth(column.colIndex);
this.setColumnWidth(column.colIndex);
});
this.instance.setBodyWidth();
}
sortRows(colIndex, sortOrder) { sortRows(colIndex, sortOrder) {
return this.datamanager.sortRows(colIndex, sortOrder); return this.datamanager.sortRows(colIndex, sortOrder);
} }
@ -1246,12 +1140,6 @@ class ColumnManager {
return this.datamanager.getColumnCount() - 1; return this.datamanager.getColumnCount() - 1;
} }
getColumnHeaderElement(colIndex) {
colIndex = +colIndex;
if (colIndex < 0) return null;
return $(`.data-table-col[data-is-header][data-col-index="${colIndex}"]`, this.wrapper);
}
getSerialColumnIndex() { getSerialColumnIndex() {
const columns = this.datamanager.getColumns(); const columns = this.datamanager.getColumns();
@ -1325,7 +1213,7 @@ class CellManager {
let $cell = this.$focusedCell; let $cell = this.$focusedCell;
if (direction === 'left') { if (direction === 'left' || direction === 'shift+tab') {
$cell = this.getLeftCell$($cell); $cell = this.getLeftCell$($cell);
} else if (direction === 'right' || direction === 'tab') { } else if (direction === 'right' || direction === 'tab') {
$cell = this.getRightCell$($cell); $cell = this.getRightCell$($cell);
@ -1361,7 +1249,7 @@ class CellManager {
return true; return true;
}; };
['left', 'right', 'up', 'down', 'tab'].map( ['left', 'right', 'up', 'down', 'tab', 'shift+tab'].map(
direction => this.keyboard.on(direction, () => focusCell(direction)) direction => this.keyboard.on(direction, () => focusCell(direction))
); );
@ -2113,7 +2001,7 @@ class BodyRenderer {
} }
}, },
/* eslint-disable */ /* eslint-disable */
no_data_text: this.options.loadingText, no_data_text: this.options.noDataMessage,
no_data_class: 'empty-state' no_data_class: 'empty-state'
/* eslint-enable */ /* eslint-enable */
}); });
@ -2153,16 +2041,33 @@ function getBodyHTML(rows) {
} }
class Style { class Style {
constructor(instance) {
this.instance = instance;
constructor(datatable) { linkProperties(this, this.instance, [
this.datatable = datatable; 'options', 'datamanager', 'columnmanager',
this.scopeClass = 'datatable-instance-' + datatable.constructor.instances; 'header', 'bodyScrollable', 'getColumn'
datatable.datatableWrapper.classList.add(this.scopeClass); ]);
this.scopeClass = 'datatable-instance-' + instance.constructor.instances;
instance.datatableWrapper.classList.add(this.scopeClass);
const styleEl = document.createElement('style'); const styleEl = document.createElement('style');
datatable.wrapper.insertBefore(styleEl, datatable.datatableWrapper); instance.wrapper.insertBefore(styleEl, instance.datatableWrapper);
this.styleEl = styleEl; this.styleEl = styleEl;
this.styleSheet = styleEl.sheet; this.styleSheet = styleEl.sheet;
this.bindResizeWindow();
}
bindResizeWindow() {
if (this.options.layout === 'fluid') {
$.on(window, 'resize', throttle(() => {
this.distributeRemainingWidth();
this.refreshColumnWidth();
this.setBodyStyle();
}, 300));
}
} }
destroy() { destroy() {
@ -2189,6 +2094,169 @@ class Style {
this.styleSheet.insertRule(ruleString, _index); this.styleSheet.insertRule(ruleString, _index);
return _index; return _index;
} }
setDimensions() {
this.setHeaderStyle();
this.setupMinWidth();
this.setupNaturalColumnWidth();
this.setupColumnWidth();
this.distributeRemainingWidth();
this.setColumnStyle();
this.setDefaultCellHeight();
this.setBodyStyle();
}
setHeaderStyle() {
if (this.options.layout === 'fluid') {
// setting width as 0 will ensure that the
// header doesn't take the available space
$.style(this.header, {
width: 0
});
}
$.style(this.header, {
margin: 0
});
// don't show resize cursor on nonResizable columns
const nonResizableColumnsSelector = this.datamanager.getColumns()
.filter(col => col.resizable === false)
.map(col => col.colIndex)
.map(i => `.data-table-header [data-col-index="${i}"]`)
.join();
this.setStyle(nonResizableColumnsSelector, {
cursor: 'pointer'
});
}
setupMinWidth() {
$.each('.data-table-col', this.header).map(col => {
const width = $.style($('.content', col), 'width');
const {
colIndex
} = $.data(col);
const column = this.getColumn(colIndex);
if (!column.minWidth) {
// only set this once
column.minWidth = width;
}
});
}
setupNaturalColumnWidth() {
if (!$('.data-table-row')) return;
// set initial width as naturally calculated by table's first row
$.each('.data-table-row[data-row-index="0"] .data-table-col', this.bodyScrollable).map($cell => {
const {
colIndex
} = $.data($cell);
const column = this.datamanager.getColumn(colIndex);
let naturalWidth = $.style($('.content', $cell), 'width');
column.naturalWidth = naturalWidth;
});
}
setupColumnWidth() {
this.datamanager.getColumns()
.map(column => {
if (column.width === null) {
column.width = column.naturalWidth;
}
if (column.width < column.minWidth) {
column.width = column.minWidth;
}
});
}
distributeRemainingWidth() {
if (this.options.layout !== 'fluid') return;
const wrapperWidth = $.style(this.instance.datatableWrapper, 'width');
const headerWidth = $.style(this.header, 'width');
const resizableColumns = this.datamanager.getColumns().filter(col => col.resizable);
const deltaWidth = (wrapperWidth - headerWidth) / resizableColumns.length;
resizableColumns.map(col => {
const width = $.style(this.getColumnHeaderElement(col.colIndex), 'width');
let finalWidth = Math.floor(width + deltaWidth) - 2;
this.datamanager.updateColumn(col.colIndex, {
width: finalWidth
});
});
}
setDefaultCellHeight() {
if (this.__cellHeightSet) return;
const height = this.options.cellHeight || $.style($('.data-table-col', this.instance.datatableWrapper), 'height');
if (height) {
this.setCellHeight(height);
this.__cellHeightSet = true;
}
}
setCellHeight(height) {
this.setStyle('.data-table-col .content', {
height: height + 'px'
});
this.setStyle('.data-table-col .edit-cell', {
height: height + 'px'
});
}
setColumnStyle() {
// align columns
this.datamanager.getColumns()
.map(column => {
// alignment
if (['left', 'center', 'right'].includes(column.align)) {
this.setStyle(`[data-col-index="${column.colIndex}"]`, {
'text-align': column.align
});
}
// width
this.columnmanager.setColumnHeaderWidth(column.colIndex);
this.columnmanager.setColumnWidth(column.colIndex);
});
this.setBodyStyle();
}
refreshColumnWidth() {
this.datamanager.getColumns()
.map(column => {
this.columnmanager.setColumnHeaderWidth(column.colIndex);
this.columnmanager.setColumnWidth(column.colIndex);
});
}
setBodyStyle() {
const width = $.style(this.header, 'width');
$.style(this.bodyScrollable, {
width: width + 'px'
});
$.style(this.bodyScrollable, {
marginTop: $.style(this.header, 'height') + 'px'
});
$.style($('table', this.bodyScrollable), {
margin: 0
});
}
getColumnHeaderElement(colIndex) {
colIndex = +colIndex;
if (colIndex < 0) return null;
return $(`.data-table-col[data-col-index="${colIndex}"]`, this.header);
}
} }
const KEYCODES = { const KEYCODES = {
@ -2291,8 +2359,9 @@ var DEFAULT_OPTIONS = {
addCheckboxColumn: false, addCheckboxColumn: false,
enableClusterize: true, enableClusterize: true,
enableLogs: false, enableLogs: false,
takeAvailableSpace: false, layout: 'fixed', // fixed, fluid
loadingText: '' noDataMessage: 'No Data',
cellHeight: null
}; };
class DataTable { class DataTable {
@ -2393,29 +2462,21 @@ class DataTable {
} }
setDimensions() { setDimensions() {
this.columnmanager.setDimensions(); this.style.setDimensions();
this.setBodyWidth();
$.style(this.bodyScrollable, {
marginTop: $.style(this.header, 'height') + 'px'
});
$.style($('table', this.bodyScrollable), {
margin: 0
});
}
setBodyWidth() {
const width = $.style(this.header, 'width');
$.style(this.bodyScrollable, { width: width + 'px' });
} }
getColumn(colIndex) { getColumn(colIndex) {
return this.datamanager.getColumn(colIndex); return this.datamanager.getColumn(colIndex);
} }
getColumns() {
return this.datamanager.getColumns();
}
getRows() {
return this.datamanager.getRows();
}
getCell(colIndex, rowIndex) { getCell(colIndex, rowIndex) {
return this.datamanager.getCell(colIndex, rowIndex); return this.datamanager.getCell(colIndex, rowIndex);
} }
@ -2470,13 +2531,13 @@ class DataTable {
DataTable.instances = 0; DataTable.instances = 0;
var name = "frappe-datatable"; var name = "frappe-datatable";
var version = "0.0.1"; var version = "0.0.2";
var description = "A modern datatable library for the web"; var description = "A modern datatable library for the web";
var main = "dist/frappe-datatable.cjs.js"; var main = "dist/frappe-datatable.cjs.js";
var scripts = {"start":"npm run dev","build":"rollup -c","dev":"rollup -c -w","test":"mocha --compilers js:babel-core/register --colors ./test/*.spec.js","test:watch":"mocha --compilers js:babel-core/register --colors -w ./test/*.spec.js"}; var scripts = {"start":"npm run dev","build":"rollup -c","dev":"rollup -c -w","test":"mocha --compilers js:babel-core/register --colors ./test/*.spec.js","test:watch":"mocha --compilers js:babel-core/register --colors -w ./test/*.spec.js"};
var devDependencies = {"chai":"3.5.0","cssnano":"^3.10.0","deepmerge":"^2.0.1","eslint":"3.19.0","eslint-loader":"1.7.1","mocha":"3.3.0","postcss-cssnext":"^3.1.0","postcss-nested":"^3.0.0","precss":"^3.1.0","rollup-plugin-json":"^2.3.0","rollup-plugin-postcss":"^1.2.8","rollup-plugin-uglify":"^3.0.0"}; var devDependencies = {"chai":"3.5.0","cssnano":"^3.10.0","deepmerge":"^2.0.1","eslint":"3.19.0","eslint-loader":"1.7.1","mocha":"3.3.0","postcss-cssnext":"^3.1.0","postcss-nested":"^3.0.0","precss":"^3.1.0","rollup-plugin-json":"^2.3.0","rollup-plugin-postcss":"^1.2.8","rollup-plugin-uglify":"^3.0.0"};
var repository = {"type":"git","url":"https://github.com/frappe/datatable.git"}; var repository = {"type":"git","url":"https://github.com/frappe/datatable.git"};
var keywords = ["webpack","es6","starter","library","universal","umd","commonjs"]; var keywords = ["datatable","data","grid","table"];
var author = "Faris Ansari"; var author = "Faris Ansari";
var license = "MIT"; var license = "MIT";
var bugs = {"url":"https://github.com/frappe/datatable/issues"}; var bugs = {"url":"https://github.com/frappe/datatable/issues"};

View File

@ -1,6 +1,6 @@
{ {
"name": "frappe-datatable", "name": "frappe-datatable",
"version": "0.0.1", "version": "0.0.2",
"description": "A modern datatable library for the web", "description": "A modern datatable library for the web",
"main": "dist/frappe-datatable.cjs.js", "main": "dist/frappe-datatable.cjs.js",
"scripts": { "scripts": {
@ -29,13 +29,10 @@
"url": "https://github.com/frappe/datatable.git" "url": "https://github.com/frappe/datatable.git"
}, },
"keywords": [ "keywords": [
"webpack", "datatable",
"es6", "data",
"starter", "grid",
"library", "table"
"universal",
"umd",
"commonjs"
], ],
"author": "Faris Ansari", "author": "Faris Ansari",
"license": "MIT", "license": "MIT",

View File

@ -29,7 +29,7 @@ const dev = {
external: ['sortablejs', 'clusterize.js'] external: ['sortablejs', 'clusterize.js']
}; };
export default [dev, Object.assign(dev, { export default [dev, Object.assign({}, dev, {
output: { output: {
format: 'cjs', format: 'cjs',
file: 'dist/frappe-datatable.cjs.js' file: 'dist/frappe-datatable.cjs.js'

View File

@ -45,5 +45,6 @@ export default {
enableClusterize: true, enableClusterize: true,
enableLogs: false, enableLogs: false,
layout: 'fixed', // fixed, fluid layout: 'fixed', // fixed, fluid
noDataMessage: 'No Data' noDataMessage: 'No Data',
cellHeight: null
}; };

View File

@ -176,7 +176,7 @@
position: relative; position: relative;
.content { .content {
padding: var(--spacer-1); padding: var(--spacer-2);
border: 2px solid transparent; border: 2px solid transparent;
&.ellipsis { &.ellipsis {
@ -189,7 +189,7 @@
.edit-cell { .edit-cell {
display: none; display: none;
// position: absolute; // position: absolute;
padding: var(--spacer-1); padding: var(--spacer-2);
background: #fff; background: #fff;
z-index: 1; z-index: 1;
height: 100%; height: 100%;

View File

@ -160,7 +160,7 @@ export default class Style {
setDefaultCellHeight() { setDefaultCellHeight() {
if (this.__cellHeightSet) return; if (this.__cellHeightSet) return;
const height = $.style($('.data-table-col', this.instance.datatableWrapper), 'height'); const height = this.options.cellHeight || $.style($('.data-table-col', this.instance.datatableWrapper), 'height');
if (height) { if (height) {
this.setCellHeight(height); this.setCellHeight(height);
this.__cellHeightSet = true; this.__cellHeightSet = true;