First commit
This commit is contained in:
commit
069f4af668
4
.babelrc
Normal file
4
.babelrc
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"presets": ["es2015"],
|
||||
"plugins": ["babel-plugin-add-module-exports"]
|
||||
}
|
||||
12
.editorconfig
Normal file
12
.editorconfig
Normal file
@ -0,0 +1,12 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = LF
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
184
.eslintrc
Normal file
184
.eslintrc
Normal file
@ -0,0 +1,184 @@
|
||||
{
|
||||
"ecmaFeatures": {
|
||||
"globalReturn": true,
|
||||
"jsx": true,
|
||||
"modules": true
|
||||
},
|
||||
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es6": true,
|
||||
"node": true
|
||||
},
|
||||
|
||||
"globals": {
|
||||
"document": false,
|
||||
"escape": false,
|
||||
"navigator": false,
|
||||
"unescape": false,
|
||||
"window": false,
|
||||
"describe": true,
|
||||
"before": true,
|
||||
"it": true,
|
||||
"expect": true,
|
||||
"sinon": true
|
||||
},
|
||||
|
||||
"parser": "babel-eslint",
|
||||
|
||||
"plugins": [
|
||||
|
||||
],
|
||||
|
||||
"rules": {
|
||||
"block-scoped-var": 2,
|
||||
"brace-style": [2, "1tbs", { "allowSingleLine": true }],
|
||||
"camelcase": [2, { "properties": "always" }],
|
||||
"comma-dangle": [2, "never"],
|
||||
"comma-spacing": [2, { "before": false, "after": true }],
|
||||
"comma-style": [2, "last"],
|
||||
"complexity": 0,
|
||||
"consistent-return": 2,
|
||||
"consistent-this": 0,
|
||||
"curly": [2, "multi-line"],
|
||||
"default-case": 0,
|
||||
"dot-location": [2, "property"],
|
||||
"dot-notation": 0,
|
||||
"eol-last": 2,
|
||||
"eqeqeq": [2, "allow-null"],
|
||||
"func-names": 0,
|
||||
"func-style": 0,
|
||||
"generator-star-spacing": [2, "both"],
|
||||
"guard-for-in": 0,
|
||||
"handle-callback-err": [2, "^(err|error|anySpecificError)$" ],
|
||||
"indent": [2, 2, { "SwitchCase": 1 }],
|
||||
"key-spacing": [2, { "beforeColon": false, "afterColon": true }],
|
||||
"keyword-spacing": [2, {"before": true, "after": true}],
|
||||
"linebreak-style": 0,
|
||||
"max-depth": 0,
|
||||
"max-len": [2, 120, 4],
|
||||
"max-nested-callbacks": 0,
|
||||
"max-params": 0,
|
||||
"max-statements": 0,
|
||||
"new-cap": [2, { "newIsCap": true, "capIsNew": false }],
|
||||
"newline-after-var": [2, "always"],
|
||||
"new-parens": 2,
|
||||
"no-alert": 0,
|
||||
"no-array-constructor": 2,
|
||||
"no-bitwise": 0,
|
||||
"no-caller": 2,
|
||||
"no-catch-shadow": 0,
|
||||
"no-cond-assign": 2,
|
||||
"no-console": 0,
|
||||
"no-constant-condition": 0,
|
||||
"no-continue": 0,
|
||||
"no-control-regex": 2,
|
||||
"no-debugger": 2,
|
||||
"no-delete-var": 2,
|
||||
"no-div-regex": 0,
|
||||
"no-dupe-args": 2,
|
||||
"no-dupe-keys": 2,
|
||||
"no-duplicate-case": 2,
|
||||
"no-else-return": 2,
|
||||
"no-empty": 0,
|
||||
"no-empty-character-class": 2,
|
||||
"no-eq-null": 0,
|
||||
"no-eval": 2,
|
||||
"no-ex-assign": 2,
|
||||
"no-extend-native": 2,
|
||||
"no-extra-bind": 2,
|
||||
"no-extra-boolean-cast": 2,
|
||||
"no-extra-parens": 0,
|
||||
"no-extra-semi": 0,
|
||||
"no-extra-strict": 0,
|
||||
"no-fallthrough": 2,
|
||||
"no-floating-decimal": 2,
|
||||
"no-func-assign": 2,
|
||||
"no-implied-eval": 2,
|
||||
"no-inline-comments": 0,
|
||||
"no-inner-declarations": [2, "functions"],
|
||||
"no-invalid-regexp": 2,
|
||||
"no-irregular-whitespace": 2,
|
||||
"no-iterator": 2,
|
||||
"no-label-var": 2,
|
||||
"no-labels": 2,
|
||||
"no-lone-blocks": 0,
|
||||
"no-lonely-if": 0,
|
||||
"no-loop-func": 0,
|
||||
"no-mixed-requires": 0,
|
||||
"no-mixed-spaces-and-tabs": [2, false],
|
||||
"no-multi-spaces": 2,
|
||||
"no-multi-str": 2,
|
||||
"no-multiple-empty-lines": [2, { "max": 1 }],
|
||||
"no-native-reassign": 2,
|
||||
"no-negated-in-lhs": 2,
|
||||
"no-nested-ternary": 0,
|
||||
"no-new": 2,
|
||||
"no-new-func": 2,
|
||||
"no-new-object": 2,
|
||||
"no-new-require": 2,
|
||||
"no-new-wrappers": 2,
|
||||
"no-obj-calls": 2,
|
||||
"no-octal": 2,
|
||||
"no-octal-escape": 2,
|
||||
"no-path-concat": 0,
|
||||
"no-plusplus": 0,
|
||||
"no-process-env": 0,
|
||||
"no-process-exit": 0,
|
||||
"no-proto": 2,
|
||||
"no-redeclare": 2,
|
||||
"no-regex-spaces": 2,
|
||||
"no-reserved-keys": 0,
|
||||
"no-restricted-modules": 0,
|
||||
"no-return-assign": 2,
|
||||
"no-script-url": 0,
|
||||
"no-self-compare": 2,
|
||||
"no-sequences": 2,
|
||||
"no-shadow": 0,
|
||||
"no-shadow-restricted-names": 2,
|
||||
"no-spaced-func": 2,
|
||||
"no-sparse-arrays": 2,
|
||||
"no-sync": 0,
|
||||
"no-ternary": 0,
|
||||
"no-throw-literal": 2,
|
||||
"no-trailing-spaces": 2,
|
||||
"no-undef": 2,
|
||||
"no-undef-init": 2,
|
||||
"no-undefined": 0,
|
||||
"no-underscore-dangle": 0,
|
||||
"no-unneeded-ternary": 2,
|
||||
"no-unreachable": 2,
|
||||
"no-unused-expressions": 0,
|
||||
"no-unused-vars": [2, { "vars": "all", "args": "none" }],
|
||||
"no-use-before-define": 2,
|
||||
"no-var": 0,
|
||||
"no-void": 0,
|
||||
"no-warning-comments": 0,
|
||||
"no-with": 2,
|
||||
"one-var": 0,
|
||||
"operator-assignment": 0,
|
||||
"operator-linebreak": [2, "after"],
|
||||
"padded-blocks": 0,
|
||||
"quote-props": 0,
|
||||
"quotes": [2, "single", "avoid-escape"],
|
||||
"radix": 2,
|
||||
"semi": [2, "always"],
|
||||
"semi-spacing": 0,
|
||||
"sort-vars": 0,
|
||||
"space-before-blocks": [2, "always"],
|
||||
"space-before-function-paren": [2, {"anonymous": "always", "named": "never"}],
|
||||
"space-in-brackets": 0,
|
||||
"space-in-parens": [2, "never"],
|
||||
"space-infix-ops": 2,
|
||||
"space-unary-ops": [2, { "words": true, "nonwords": false }],
|
||||
"spaced-comment": [2, "always"],
|
||||
"strict": 0,
|
||||
"use-isnan": 2,
|
||||
"valid-jsdoc": 0,
|
||||
"valid-typeof": 2,
|
||||
"vars-on-top": 2,
|
||||
"wrap-iife": [2, "any"],
|
||||
"wrap-regex": 0,
|
||||
"yoda": [2, "never"]
|
||||
}
|
||||
}
|
||||
31
.gitignore
vendored
Normal file
31
.gitignore
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directory
|
||||
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
|
||||
node_modules
|
||||
|
||||
# Remove some common IDE working directories
|
||||
.idea
|
||||
.vscode
|
||||
22
LICENSE
Normal file
22
LICENSE
Normal file
@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017 Faris Ansari
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
83
README.md
Normal file
83
README.md
Normal file
@ -0,0 +1,83 @@
|
||||
# Webpack library starter
|
||||
|
||||
Webpack based boilerplate for producing libraries (Input: ES6, Output: universal library)
|
||||
|
||||
## Features
|
||||
|
||||
* Webpack 3 based.
|
||||
* ES6 as a source.
|
||||
* Exports in a [umd](https://github.com/umdjs/umd) format so your library works everywhere.
|
||||
* ES6 test setup with [Mocha](http://mochajs.org/) and [Chai](http://chaijs.com/).
|
||||
* Linting with [ESLint](http://eslint.org/).
|
||||
|
||||
## Process
|
||||
|
||||
```
|
||||
ES6 source files
|
||||
|
|
||||
|
|
||||
webpack
|
||||
|
|
||||
+--- babel, eslint
|
||||
|
|
||||
ready to use
|
||||
library
|
||||
in umd format
|
||||
```
|
||||
|
||||
*Have in mind that you have to build your library before publishing. The files under the `lib` folder are the ones that should be distributed.*
|
||||
|
||||
## Getting started
|
||||
|
||||
1. Setting up the name of your library
|
||||
* Open `webpack.config.js` file and change the value of `libraryName` variable.
|
||||
* Open `package.json` file and change the value of `main` property so it matches the name of your library.
|
||||
2. Build your library
|
||||
* Run `npm install` to get the project's dependencies
|
||||
* Run `npm run build` to produce minified version of your library.
|
||||
3. Development mode
|
||||
* Having all the dependencies installed run `npm run dev`. This command will generate an non-minified version of your library and will run a watcher so you get the compilation on file change.
|
||||
4. Running the tests
|
||||
* Run `npm run test`
|
||||
|
||||
## Scripts
|
||||
|
||||
* `npm run build` - produces production version of your library under the `lib` folder
|
||||
* `npm run dev` - produces development version of your library and runs a watcher
|
||||
* `npm run test` - well ... it runs the tests :)
|
||||
* `npm run test:watch` - same as above but in a watch mode
|
||||
|
||||
## Readings
|
||||
|
||||
* [Start your own JavaScript library using webpack and ES6](http://krasimirtsonev.com/blog/article/javascript-library-starter-using-webpack-es6)
|
||||
|
||||
## Misc
|
||||
|
||||
### An example of using dependencies that shouldn’t be resolved by webpack, but should become dependencies of the resulting bundle
|
||||
|
||||
In the following example we are excluding React and Lodash:
|
||||
|
||||
```js
|
||||
{
|
||||
devtool: 'source-map',
|
||||
output: {
|
||||
path: '...',
|
||||
libraryTarget: 'umd',
|
||||
library: '...'
|
||||
},
|
||||
entry: '...',
|
||||
...
|
||||
externals: {
|
||||
react: 'react'
|
||||
// Use more complicated mapping for lodash.
|
||||
// We need to access it differently depending
|
||||
// on the environment.
|
||||
lodash: {
|
||||
commonjs: 'lodash',
|
||||
commonjs2: 'lodash',
|
||||
amd: '_',
|
||||
root: '_'
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
494
lib/ReGrid.js
Normal file
494
lib/ReGrid.js
Normal file
@ -0,0 +1,494 @@
|
||||
(function webpackUniversalModuleDefinition(root, factory) {
|
||||
if(typeof exports === 'object' && typeof module === 'object')
|
||||
module.exports = factory();
|
||||
else if(typeof define === 'function' && define.amd)
|
||||
define("ReGrid", [], factory);
|
||||
else if(typeof exports === 'object')
|
||||
exports["ReGrid"] = factory();
|
||||
else
|
||||
root["ReGrid"] = factory();
|
||||
})(this, function() {
|
||||
return /******/ (function(modules) { // webpackBootstrap
|
||||
/******/ // The module cache
|
||||
/******/ var installedModules = {};
|
||||
/******/
|
||||
/******/ // The require function
|
||||
/******/ function __webpack_require__(moduleId) {
|
||||
/******/
|
||||
/******/ // Check if module is in cache
|
||||
/******/ if(installedModules[moduleId]) {
|
||||
/******/ return installedModules[moduleId].exports;
|
||||
/******/ }
|
||||
/******/ // Create a new module (and put it into the cache)
|
||||
/******/ var module = installedModules[moduleId] = {
|
||||
/******/ i: moduleId,
|
||||
/******/ l: false,
|
||||
/******/ exports: {}
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // Execute the module function
|
||||
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
||||
/******/
|
||||
/******/ // Flag the module as loaded
|
||||
/******/ module.l = true;
|
||||
/******/
|
||||
/******/ // Return the exports of the module
|
||||
/******/ return module.exports;
|
||||
/******/ }
|
||||
/******/
|
||||
/******/
|
||||
/******/ // expose the modules object (__webpack_modules__)
|
||||
/******/ __webpack_require__.m = modules;
|
||||
/******/
|
||||
/******/ // expose the module cache
|
||||
/******/ __webpack_require__.c = installedModules;
|
||||
/******/
|
||||
/******/ // define getter function for harmony exports
|
||||
/******/ __webpack_require__.d = function(exports, name, getter) {
|
||||
/******/ if(!__webpack_require__.o(exports, name)) {
|
||||
/******/ Object.defineProperty(exports, name, {
|
||||
/******/ configurable: false,
|
||||
/******/ enumerable: true,
|
||||
/******/ get: getter
|
||||
/******/ });
|
||||
/******/ }
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
||||
/******/ __webpack_require__.n = function(module) {
|
||||
/******/ var getter = module && module.__esModule ?
|
||||
/******/ function getDefault() { return module['default']; } :
|
||||
/******/ function getModuleExports() { return module; };
|
||||
/******/ __webpack_require__.d(getter, 'a', getter);
|
||||
/******/ return getter;
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // Object.prototype.hasOwnProperty.call
|
||||
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
|
||||
/******/
|
||||
/******/ // __webpack_public_path__
|
||||
/******/ __webpack_require__.p = "";
|
||||
/******/
|
||||
/******/ // Load entry module and return exports
|
||||
/******/ return __webpack_require__(__webpack_require__.s = 0);
|
||||
/******/ })
|
||||
/************************************************************************/
|
||||
/******/ ([
|
||||
/* 0 */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.ReGrid = undefined;
|
||||
|
||||
var _regrid = __webpack_require__(1);
|
||||
|
||||
var _regrid2 = _interopRequireDefault(_regrid);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
exports.ReGrid = _regrid2.default;
|
||||
|
||||
/***/ }),
|
||||
/* 1 */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
||||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
||||
|
||||
var _utils = __webpack_require__(2);
|
||||
|
||||
var _jQuery = __webpack_require__(!(function webpackMissingModule() { var e = new Error("Cannot find module \"jQuery\""); e.code = 'MODULE_NOT_FOUND'; throw e; }()));
|
||||
|
||||
var _jQuery2 = _interopRequireDefault(_jQuery);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
var ReGrid = function () {
|
||||
function ReGrid(_ref) {
|
||||
var wrapper = _ref.wrapper,
|
||||
events = _ref.events;
|
||||
|
||||
_classCallCheck(this, ReGrid);
|
||||
|
||||
this.wrapper = wrapper;
|
||||
this.events = events || {};
|
||||
this.makeDom();
|
||||
this.bindEvents();
|
||||
}
|
||||
|
||||
_createClass(ReGrid, [{
|
||||
key: 'makeDom',
|
||||
value: function makeDom() {
|
||||
this.wrapper.html('\n <div class="data-table">\n <table class="data-table-header table table-bordered">\n </table>\n <div class="body-scrollable">\n <table class="data-table-body table table-bordered">\n </table>\n </div>\n <div class="data-table-footer">\n </div>\n <div class="data-table-popup">\n <div class="edit-popup"></div>\n </div>\n </div>\n ');
|
||||
|
||||
this.header = this.wrapper.find('.data-table-header');
|
||||
this.bodyScrollable = this.wrapper.find('.body-scrollable');
|
||||
this.body = this.wrapper.find('.data-table-body');
|
||||
this.footer = this.wrapper.find('.data-table-footer');
|
||||
}
|
||||
}, {
|
||||
key: 'render',
|
||||
value: function render(_ref2) {
|
||||
var columns = _ref2.columns,
|
||||
rows = _ref2.rows;
|
||||
|
||||
if (this.wrapper.find('.data-table').length === 0) {
|
||||
this.makeDom();
|
||||
this.bindEvents();
|
||||
}
|
||||
|
||||
this.columns = this.prepareColumns(columns);
|
||||
this.rows = this.prepareRows(rows);
|
||||
|
||||
this.header.html((0, _utils.getHeader)(this.columns));
|
||||
this.body.html((0, _utils.getBody)(this.rows));
|
||||
|
||||
this.setDimensions();
|
||||
}
|
||||
}, {
|
||||
key: 'updateCell',
|
||||
value: function updateCell(rowIndex, colIndex, value) {
|
||||
var row = this.getRow(rowIndex);
|
||||
var cell = row.find(function (cell) {
|
||||
return cell.col_index === colIndex;
|
||||
});
|
||||
|
||||
cell.data = value;
|
||||
this.refreshCell(cell);
|
||||
}
|
||||
}, {
|
||||
key: 'refreshRows',
|
||||
value: function refreshRows(rows) {
|
||||
if (rows) {
|
||||
this.rows = this.prepareRows(rows);
|
||||
}
|
||||
this.body.html((0, _utils.getBody)(this.rows));
|
||||
this.setDimensions();
|
||||
}
|
||||
}, {
|
||||
key: 'refreshCell',
|
||||
value: function refreshCell(cell) {
|
||||
var selector = '.data-table-col[data-row-index="' + cell.row_index + '"][data-col-index="' + cell.col_index + '"]';
|
||||
var $cell = this.body.find(selector);
|
||||
var $newCell = (0, _jQuery2.default)((0, _utils.getCell)(cell));
|
||||
|
||||
$cell.replaceWith($newCell);
|
||||
}
|
||||
}, {
|
||||
key: 'prepareColumns',
|
||||
value: function prepareColumns(columns) {
|
||||
return columns.map(function (col, i) {
|
||||
col.colIndex = i;
|
||||
col.isHeader = 1;
|
||||
col.format = function (val) {
|
||||
return '<span>' + val + '</span>';
|
||||
};
|
||||
return col;
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'prepareRows',
|
||||
value: function prepareRows(rows) {
|
||||
return rows.map(function (cells, i) {
|
||||
return cells.map(function (cell, j) {
|
||||
cell.colIndex = j;
|
||||
cell.rowIndex = i;
|
||||
return cell;
|
||||
});
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'bindEvents',
|
||||
value: function bindEvents() {
|
||||
var me = this;
|
||||
|
||||
this.bodyScrollable.on('click', '.data-table-col', function () {
|
||||
var $col = (0, _jQuery2.default)(this);
|
||||
|
||||
me.bodyScrollable.find('.data-table-col').removeClass('selected');
|
||||
$col.addClass('selected');
|
||||
});
|
||||
|
||||
this.bindCellDoubleClick();
|
||||
this.bindResizeColumn();
|
||||
this.bindSortColumn();
|
||||
}
|
||||
}, {
|
||||
key: 'setDimensions',
|
||||
value: function setDimensions() {
|
||||
var me = this;
|
||||
|
||||
// set the width for each cell
|
||||
this.header.find('.data-table-col').each(function () {
|
||||
var col = (0, _jQuery2.default)(this);
|
||||
var height = col.find('.content').height();
|
||||
var width = col.find('.content').width();
|
||||
var colIndex = col.attr('data-col-index');
|
||||
var selector = '.data-table-col[data-col-index="' + colIndex + '"] .content';
|
||||
var $cell = me.bodyScrollable.find(selector);
|
||||
|
||||
$cell.width(width);
|
||||
$cell.height(height);
|
||||
});
|
||||
|
||||
// setting width as 0 will ensure that the
|
||||
// header doesn't take the available space
|
||||
this.header.css({
|
||||
width: 0,
|
||||
margin: 0
|
||||
});
|
||||
|
||||
this.bodyScrollable.css({
|
||||
width: this.header.css('width'),
|
||||
marginTop: this.header.height() + 1
|
||||
});
|
||||
|
||||
this.bodyScrollable.find('.table').css('margin', 0);
|
||||
}
|
||||
}, {
|
||||
key: 'bindCellDoubleClick',
|
||||
value: function bindCellDoubleClick() {
|
||||
var events = this.events;
|
||||
|
||||
|
||||
var $editPopup = this.wrapper.find('.edit-popup');
|
||||
|
||||
$editPopup.hide();
|
||||
|
||||
this.bodyScrollable.on('dblclick', '.data-table-col', function () {
|
||||
var $cell = (0, _jQuery2.default)(this);
|
||||
var rowIndex = $cell.attr('data-row-index');
|
||||
var colIndex = $cell.attr('data-col-index');
|
||||
|
||||
$editPopup.empty();
|
||||
|
||||
var _$cell$position = $cell.position(),
|
||||
top = _$cell$position.top,
|
||||
left = _$cell$position.left;
|
||||
|
||||
$editPopup.css({
|
||||
top: top - 12,
|
||||
left: left - 12
|
||||
});
|
||||
|
||||
// showing the popup is the responsibility of event handler
|
||||
events.on_cell_doubleclick($cell.get(0), $editPopup, rowIndex, colIndex);
|
||||
});
|
||||
|
||||
(0, _jQuery2.default)(document.body).on('click', function (e) {
|
||||
if ((0, _jQuery2.default)(e.target).is('.edit-popup, .edit-popup *')) return;
|
||||
$editPopup.hide();
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'bindResizeColumn',
|
||||
value: function bindResizeColumn() {
|
||||
var me = this;
|
||||
var isDragging = false;
|
||||
var $currCell = void 0,
|
||||
startWidth = void 0,
|
||||
startX = void 0;
|
||||
|
||||
this.header.on('mousedown', '.data-table-col', function (e) {
|
||||
$currCell = (0, _jQuery2.default)(this);
|
||||
var col = me.getColumn($currCell.attr('data-col-index'));
|
||||
|
||||
if (col && col.resizable === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
isDragging = true;
|
||||
startWidth = $currCell.find('.content').width();
|
||||
startX = e.pageX;
|
||||
});
|
||||
|
||||
(0, _jQuery2.default)('body').on('mouseup', function (e) {
|
||||
if (!$currCell) return;
|
||||
isDragging = false;
|
||||
var colIndex = $currCell.attr('data-col-index');
|
||||
|
||||
if ($currCell) {
|
||||
var width = $currCell.find('.content').css('width');
|
||||
|
||||
me.setColumnWidth(colIndex, width);
|
||||
me.bodyScrollable.css('width', me.header.css('width'));
|
||||
$currCell = null;
|
||||
}
|
||||
});
|
||||
|
||||
this.header.on('mousemove', '.data-table-col', function (e) {
|
||||
if (!isDragging) return;
|
||||
var fwidth = startWidth + (e.pageX - startX);
|
||||
|
||||
$currCell.find('.content').width(fwidth);
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'bindSortColumn',
|
||||
value: function bindSortColumn() {
|
||||
var me = this;
|
||||
|
||||
this.header.on('click', '.data-table-col .content span', function () {
|
||||
var $cell = (0, _jQuery2.default)(this).closest('.data-table-col');
|
||||
var sortBy = $cell.attr('data-sort-by');
|
||||
var colIndex = $cell.attr('data-col-index');
|
||||
|
||||
if (sortBy === 'none') {
|
||||
$cell.attr('data-sort-by', 'asc');
|
||||
$cell.find('.content').append('<span class="octicon octicon-chevron-up">');
|
||||
} else if (sortBy === 'asc') {
|
||||
$cell.attr('data-sort-by', 'desc');
|
||||
$cell.find('.content .octicon').removeClass('octicon-chevron-up').addClass('octicon-chevron-down');
|
||||
} else if (sortBy === 'desc') {
|
||||
$cell.attr('data-sort-by', 'none');
|
||||
$cell.find('.content .octicon').remove();
|
||||
}
|
||||
|
||||
var sortByAction = $cell.attr('data-sort-by');
|
||||
|
||||
if (me.events.on_sort) {
|
||||
me.events.on_sort.apply(null, [colIndex, sortByAction]);
|
||||
} else {
|
||||
me.sortRows(colIndex, sortByAction);
|
||||
me.refreshRows();
|
||||
}
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'sortRows',
|
||||
value: function sortRows(colIndex) {
|
||||
var sortBy = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'none';
|
||||
|
||||
this.rows.sort(function (a, b) {
|
||||
var _aIndex = a[0].row_index;
|
||||
var _bIndex = b[0].row_index;
|
||||
var _a = a[colIndex].data;
|
||||
var _b = b[colIndex].data;
|
||||
|
||||
if (sortBy === 'none') {
|
||||
return _aIndex - _bIndex;
|
||||
} else if (sortBy === 'asc') {
|
||||
if (_a < _b) return -1;
|
||||
if (_a > _b) return 1;
|
||||
if (_a === _b) return 0;
|
||||
} else if (sortBy === 'desc') {
|
||||
if (_a < _b) return 1;
|
||||
if (_a > _b) return -1;
|
||||
if (_a === _b) return 0;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'setColumnWidth',
|
||||
value: function setColumnWidth(colIndex, width) {
|
||||
var header = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
||||
|
||||
var selector = '.data-table-col[data-col-index="' + colIndex + '"] .content';
|
||||
var $el = void 0;
|
||||
|
||||
if (header) {
|
||||
$el = this.header.find(selector);
|
||||
} else {
|
||||
$el = this.bodyScrollable.find(selector);
|
||||
}
|
||||
$el.css('width', width);
|
||||
}
|
||||
}, {
|
||||
key: 'getColumn',
|
||||
value: function getColumn(colIndex) {
|
||||
return this.columns.find(function (col) {
|
||||
return col.col_index === colIndex;
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'getRow',
|
||||
value: function getRow(rowIndex) {
|
||||
return this.rows.find(function (row) {
|
||||
return row[0].row_index === rowIndex;
|
||||
});
|
||||
}
|
||||
}]);
|
||||
|
||||
return ReGrid;
|
||||
}();
|
||||
|
||||
exports.default = ReGrid;
|
||||
module.exports = exports['default'];
|
||||
|
||||
/***/ }),
|
||||
/* 2 */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
||||
var _jQuery = __webpack_require__(!(function webpackMissingModule() { var e = new Error("Cannot find module \"jQuery\""); e.code = 'MODULE_NOT_FOUND'; throw e; }()));
|
||||
|
||||
var _jQuery2 = _interopRequireDefault(_jQuery);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function getCell(cell) {
|
||||
var customAttr = [!isNaN(cell.colIndex) ? 'data-col-index="' + cell.colIndex + '"' : '', !isNaN(cell.rowIndex) ? 'data-row-index="' + cell.rowIndex + '"' : '', cell.isHeader ? 'data-sort-by="none"' : ''].join(' ');
|
||||
|
||||
return '\n <td class="data-table-col noselect" ' + customAttr + '>\n <div class="content ellipsis">\n ' + (cell.format ? cell.format(cell.data) : cell.data) + '\n </div>\n </td>\n ';
|
||||
}
|
||||
|
||||
function getRow(row) {
|
||||
var header = row.isHeader ? 'data-header' : '';
|
||||
var cells = row.cells;
|
||||
var dataRowIndex = !isNaN(cells[0].rowIndex) ? 'data-row-index="' + cells[0].rowIndex + '"' : '';
|
||||
|
||||
return '\n <tr class="data-table-row" ' + dataRowIndex + ' ' + header + '>\n ' + cells.map(getCell).join('') + '\n </tr>\n ';
|
||||
}
|
||||
|
||||
function getHeader(columns) {
|
||||
var $header = (0, _jQuery2.default)('<thead>\n ' + getRow({ cells: columns, isHeader: 1 }) + '\n </thead>\n ');
|
||||
|
||||
columns.map(function (col) {
|
||||
if (!col.width) return;
|
||||
var $cellContent = $header.find('.data-table-col[data-col-index="' + col.colIndex + '"] .content');
|
||||
|
||||
$cellContent.width(col.width);
|
||||
// $cell_content.css('max-width', col.width + 'px');
|
||||
});
|
||||
|
||||
return $header;
|
||||
}
|
||||
|
||||
function getBody(rows) {
|
||||
return '<tbody>\n ' + rows.map(function (row) {
|
||||
return getRow({ cells: row });
|
||||
}).join('') + '\n </tbody>\n ';
|
||||
}
|
||||
|
||||
exports.default = {
|
||||
getHeader: getHeader,
|
||||
getBody: getBody,
|
||||
getRow: getRow,
|
||||
getCell: getCell
|
||||
};
|
||||
module.exports = exports['default'];
|
||||
|
||||
/***/ })
|
||||
/******/ ]);
|
||||
});
|
||||
//# sourceMappingURL=ReGrid.js.map
|
||||
1
lib/ReGrid.js.map
Normal file
1
lib/ReGrid.js.map
Normal file
File diff suppressed because one or more lines are too long
45
package.json
Normal file
45
package.json
Normal file
@ -0,0 +1,45 @@
|
||||
{
|
||||
"name": "regrid",
|
||||
"version": "0.0.1",
|
||||
"description": "A modern grid for the web",
|
||||
"main": "lib/regrid.js",
|
||||
"scripts": {
|
||||
"build": "webpack --env build",
|
||||
"dev": "webpack --progress --colors --watch --env dev",
|
||||
"test": "mocha --compilers js:babel-core/register --colors ./test/*.spec.js",
|
||||
"test:watch": "mocha --compilers js:babel-core/register --colors -w ./test/*.spec.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-cli": "6.24.1",
|
||||
"babel-core": "6.24.1",
|
||||
"babel-eslint": "7.2.3",
|
||||
"babel-loader": "7.0.0",
|
||||
"babel-plugin-add-module-exports": "0.2.1",
|
||||
"babel-preset-es2015": "6.24.1",
|
||||
"chai": "3.5.0",
|
||||
"eslint": "3.19.0",
|
||||
"eslint-loader": "1.7.1",
|
||||
"mocha": "3.3.0",
|
||||
"webpack": "3.1.0",
|
||||
"yargs": "7.1.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/netchampfaris/regrid.git"
|
||||
},
|
||||
"keywords": [
|
||||
"webpack",
|
||||
"es6",
|
||||
"starter",
|
||||
"library",
|
||||
"universal",
|
||||
"umd",
|
||||
"commonjs"
|
||||
],
|
||||
"author": "Faris Ansari",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/netchampfaris/regrid/issues"
|
||||
},
|
||||
"homepage": "https://github.com/netchampfaris/regrid"
|
||||
}
|
||||
2
src/index.js
Normal file
2
src/index.js
Normal file
@ -0,0 +1,2 @@
|
||||
import ReGrid from './regrid.js';
|
||||
export { ReGrid };
|
||||
291
src/regrid.js
Normal file
291
src/regrid.js
Normal file
@ -0,0 +1,291 @@
|
||||
import { getHeader, getBody, getCell } from './utils.js';
|
||||
import $ from 'jQuery';
|
||||
|
||||
export default class ReGrid {
|
||||
constructor({ wrapper, events }) {
|
||||
this.wrapper = wrapper;
|
||||
this.events = events || {};
|
||||
this.makeDom();
|
||||
this.bindEvents();
|
||||
}
|
||||
|
||||
makeDom() {
|
||||
this.wrapper.html(`
|
||||
<div class="data-table">
|
||||
<table class="data-table-header table table-bordered">
|
||||
</table>
|
||||
<div class="body-scrollable">
|
||||
<table class="data-table-body table table-bordered">
|
||||
</table>
|
||||
</div>
|
||||
<div class="data-table-footer">
|
||||
</div>
|
||||
<div class="data-table-popup">
|
||||
<div class="edit-popup"></div>
|
||||
</div>
|
||||
</div>
|
||||
`);
|
||||
|
||||
this.header = this.wrapper.find('.data-table-header');
|
||||
this.bodyScrollable = this.wrapper.find('.body-scrollable');
|
||||
this.body = this.wrapper.find('.data-table-body');
|
||||
this.footer = this.wrapper.find('.data-table-footer');
|
||||
}
|
||||
|
||||
render({ columns, rows }) {
|
||||
if (this.wrapper.find('.data-table').length === 0) {
|
||||
this.makeDom();
|
||||
this.bindEvents();
|
||||
}
|
||||
|
||||
this.columns = this.prepareColumns(columns);
|
||||
this.rows = this.prepareRows(rows);
|
||||
|
||||
this.header.html(getHeader(this.columns));
|
||||
this.body.html(getBody(this.rows));
|
||||
|
||||
this.setDimensions();
|
||||
}
|
||||
|
||||
updateCell(rowIndex, colIndex, value) {
|
||||
const row = this.getRow(rowIndex);
|
||||
const cell = row.find(cell => cell.col_index === colIndex);
|
||||
|
||||
cell.data = value;
|
||||
this.refreshCell(cell);
|
||||
}
|
||||
|
||||
refreshRows(rows) {
|
||||
if (rows) {
|
||||
this.rows = this.prepareRows(rows);
|
||||
}
|
||||
this.body.html(getBody(this.rows));
|
||||
this.setDimensions();
|
||||
}
|
||||
|
||||
refreshCell(cell) {
|
||||
const selector = `.data-table-col[data-row-index="${cell.row_index}"][data-col-index="${cell.col_index}"]`;
|
||||
const $cell = this.body.find(selector);
|
||||
const $newCell = $(getCell(cell));
|
||||
|
||||
$cell.replaceWith($newCell);
|
||||
}
|
||||
|
||||
prepareColumns(columns) {
|
||||
return columns.map((col, i) => {
|
||||
col.colIndex = i;
|
||||
col.isHeader = 1;
|
||||
col.format = val => `<span>${val}</span>`;
|
||||
return col;
|
||||
});
|
||||
}
|
||||
|
||||
prepareRows(rows) {
|
||||
return rows.map((cells, i) => {
|
||||
return cells.map((cell, j) => {
|
||||
cell.colIndex = j;
|
||||
cell.rowIndex = i;
|
||||
return cell;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
bindEvents() {
|
||||
const me = this;
|
||||
|
||||
this.bodyScrollable.on('click', '.data-table-col', function () {
|
||||
const $col = $(this);
|
||||
|
||||
me.bodyScrollable.find('.data-table-col').removeClass('selected');
|
||||
$col.addClass('selected');
|
||||
});
|
||||
|
||||
this.bindCellDoubleClick();
|
||||
this.bindResizeColumn();
|
||||
this.bindSortColumn();
|
||||
}
|
||||
|
||||
setDimensions() {
|
||||
const me = this;
|
||||
|
||||
// set the width for each cell
|
||||
this.header.find('.data-table-col').each(function () {
|
||||
const col = $(this);
|
||||
const height = col.find('.content').height();
|
||||
const width = col.find('.content').width();
|
||||
const colIndex = col.attr('data-col-index');
|
||||
const selector = `.data-table-col[data-col-index="${colIndex}"] .content`;
|
||||
const $cell = me.bodyScrollable.find(selector);
|
||||
|
||||
$cell.width(width);
|
||||
$cell.height(height);
|
||||
});
|
||||
|
||||
// setting width as 0 will ensure that the
|
||||
// header doesn't take the available space
|
||||
this.header.css({
|
||||
width: 0,
|
||||
margin: 0
|
||||
});
|
||||
|
||||
this.bodyScrollable.css({
|
||||
width: this.header.css('width'),
|
||||
marginTop: this.header.height() + 1
|
||||
});
|
||||
|
||||
this.bodyScrollable.find('.table').css('margin', 0);
|
||||
}
|
||||
|
||||
bindCellDoubleClick() {
|
||||
const { events } = this;
|
||||
|
||||
const $editPopup = this.wrapper.find('.edit-popup');
|
||||
|
||||
$editPopup.hide();
|
||||
|
||||
this.bodyScrollable.on('dblclick', '.data-table-col', function () {
|
||||
const $cell = $(this);
|
||||
const rowIndex = $cell.attr('data-row-index');
|
||||
const colIndex = $cell.attr('data-col-index');
|
||||
|
||||
$editPopup.empty();
|
||||
const { top, left } = $cell.position();
|
||||
|
||||
$editPopup.css({
|
||||
top: top - 12,
|
||||
left: left - 12
|
||||
});
|
||||
|
||||
// showing the popup is the responsibility of event handler
|
||||
events.on_cell_doubleclick(
|
||||
$cell.get(0),
|
||||
$editPopup,
|
||||
rowIndex,
|
||||
colIndex
|
||||
);
|
||||
});
|
||||
|
||||
$(document.body).on('click', e => {
|
||||
if ($(e.target).is('.edit-popup, .edit-popup *')) return;
|
||||
$editPopup.hide();
|
||||
});
|
||||
}
|
||||
|
||||
bindResizeColumn() {
|
||||
const me = this;
|
||||
let isDragging = false;
|
||||
let $currCell, startWidth, startX;
|
||||
|
||||
this.header.on('mousedown', '.data-table-col', function (e) {
|
||||
$currCell = $(this);
|
||||
const col = me.getColumn($currCell.attr('data-col-index'));
|
||||
|
||||
if (col && col.resizable === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
isDragging = true;
|
||||
startWidth = $currCell.find('.content').width();
|
||||
startX = e.pageX;
|
||||
});
|
||||
|
||||
$('body').on('mouseup', function (e) {
|
||||
if (!$currCell) return;
|
||||
isDragging = false;
|
||||
const colIndex = $currCell.attr('data-col-index');
|
||||
|
||||
if ($currCell) {
|
||||
const width = $currCell.find('.content').css('width');
|
||||
|
||||
me.setColumnWidth(colIndex, width);
|
||||
me.bodyScrollable.css('width', me.header.css('width'));
|
||||
$currCell = null;
|
||||
}
|
||||
});
|
||||
|
||||
this.header.on('mousemove', '.data-table-col', function (e) {
|
||||
if (!isDragging) return;
|
||||
const fwidth = startWidth + (e.pageX - startX);
|
||||
|
||||
$currCell.find('.content').width(fwidth);
|
||||
});
|
||||
}
|
||||
|
||||
bindSortColumn() {
|
||||
const me = this;
|
||||
|
||||
this.header.on('click', '.data-table-col .content span', function () {
|
||||
const $cell = $(this).closest('.data-table-col');
|
||||
const sortBy = $cell.attr('data-sort-by');
|
||||
const colIndex = $cell.attr('data-col-index');
|
||||
|
||||
if (sortBy === 'none') {
|
||||
$cell.attr('data-sort-by', 'asc');
|
||||
$cell
|
||||
.find('.content')
|
||||
.append('<span class="octicon octicon-chevron-up">');
|
||||
} else if (sortBy === 'asc') {
|
||||
$cell.attr('data-sort-by', 'desc');
|
||||
$cell
|
||||
.find('.content .octicon')
|
||||
.removeClass('octicon-chevron-up')
|
||||
.addClass('octicon-chevron-down');
|
||||
} else if (sortBy === 'desc') {
|
||||
$cell.attr('data-sort-by', 'none');
|
||||
$cell.find('.content .octicon').remove();
|
||||
}
|
||||
|
||||
const sortByAction = $cell.attr('data-sort-by');
|
||||
|
||||
if (me.events.on_sort) {
|
||||
me.events.on_sort.apply(null, [colIndex, sortByAction]);
|
||||
} else {
|
||||
me.sortRows(colIndex, sortByAction);
|
||||
me.refreshRows();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
sortRows(colIndex, sortBy = 'none') {
|
||||
this.rows.sort((a, b) => {
|
||||
const _aIndex = a[0].row_index;
|
||||
const _bIndex = b[0].row_index;
|
||||
const _a = a[colIndex].data;
|
||||
const _b = b[colIndex].data;
|
||||
|
||||
if (sortBy === 'none') {
|
||||
return _aIndex - _bIndex;
|
||||
} else if (sortBy === 'asc') {
|
||||
if (_a < _b) return -1;
|
||||
if (_a > _b) return 1;
|
||||
if (_a === _b) return 0;
|
||||
} else if (sortBy === 'desc') {
|
||||
if (_a < _b) return 1;
|
||||
if (_a > _b) return -1;
|
||||
if (_a === _b) return 0;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
setColumnWidth(colIndex, width, header = false) {
|
||||
const selector = `.data-table-col[data-col-index="${colIndex}"] .content`;
|
||||
let $el;
|
||||
|
||||
if (header) {
|
||||
$el = this.header.find(selector);
|
||||
} else {
|
||||
$el = this.bodyScrollable.find(selector);
|
||||
}
|
||||
$el.css('width', width);
|
||||
}
|
||||
|
||||
getColumn(colIndex) {
|
||||
return this.columns.find(col => col.col_index === colIndex);
|
||||
}
|
||||
|
||||
getRow(rowIndex) {
|
||||
return this.rows.find(row => row[0].row_index === rowIndex);
|
||||
}
|
||||
}
|
||||
|
||||
63
src/utils.js
Normal file
63
src/utils.js
Normal file
@ -0,0 +1,63 @@
|
||||
import $ from 'jQuery';
|
||||
|
||||
function getCell(cell) {
|
||||
const customAttr = [
|
||||
!isNaN(cell.colIndex) ? `data-col-index="${cell.colIndex}"` : '',
|
||||
!isNaN(cell.rowIndex) ? `data-row-index="${cell.rowIndex}"` : '',
|
||||
cell.isHeader ? 'data-sort-by="none"' : ''
|
||||
].join(' ');
|
||||
|
||||
return `
|
||||
<td class="data-table-col noselect" ${customAttr}>
|
||||
<div class="content ellipsis">
|
||||
${cell.format ? cell.format(cell.data) : cell.data}
|
||||
</div>
|
||||
</td>
|
||||
`;
|
||||
}
|
||||
|
||||
function getRow(row) {
|
||||
const header = row.isHeader ? 'data-header' : '';
|
||||
const cells = row.cells;
|
||||
const dataRowIndex = !isNaN(cells[0].rowIndex) ?
|
||||
`data-row-index="${cells[0].rowIndex}"` : '';
|
||||
|
||||
return `
|
||||
<tr class="data-table-row" ${dataRowIndex} ${header}>
|
||||
${cells.map(getCell).join('')}
|
||||
</tr>
|
||||
`;
|
||||
}
|
||||
|
||||
function getHeader(columns) {
|
||||
const $header = $(`<thead>
|
||||
${getRow({ cells: columns, isHeader: 1 })}
|
||||
</thead>
|
||||
`);
|
||||
|
||||
columns.map(col => {
|
||||
if (!col.width) return;
|
||||
const $cellContent = $header.find(
|
||||
`.data-table-col[data-col-index="${col.colIndex}"] .content`
|
||||
);
|
||||
|
||||
$cellContent.width(col.width);
|
||||
// $cell_content.css('max-width', col.width + 'px');
|
||||
});
|
||||
|
||||
return $header;
|
||||
}
|
||||
|
||||
function getBody(rows) {
|
||||
return `<tbody>
|
||||
${rows.map(row => getRow({ cells: row })).join('')}
|
||||
</tbody>
|
||||
`;
|
||||
}
|
||||
|
||||
export default {
|
||||
getHeader,
|
||||
getBody,
|
||||
getRow,
|
||||
getCell
|
||||
};
|
||||
32
test/regrid.spec.js
Normal file
32
test/regrid.spec.js
Normal file
@ -0,0 +1,32 @@
|
||||
/* global describe, it, before */
|
||||
|
||||
import chai from 'chai';
|
||||
import {Cat, Dog} from '../lib/regrid.js';
|
||||
|
||||
chai.expect();
|
||||
|
||||
const expect = chai.expect;
|
||||
|
||||
let lib;
|
||||
|
||||
describe('Given an instance of my Cat library', () => {
|
||||
before(() => {
|
||||
lib = new Cat();
|
||||
});
|
||||
describe('when I need the name', () => {
|
||||
it('should return the name', () => {
|
||||
expect(lib.name).to.be.equal('Cat');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Given an instance of my Dog library', () => {
|
||||
before(() => {
|
||||
lib = new Dog();
|
||||
});
|
||||
describe('when I need the name', () => {
|
||||
it('should return the name', () => {
|
||||
expect(lib.name).to.be.equal('Dog');
|
||||
});
|
||||
});
|
||||
});
|
||||
50
webpack.config.js
Normal file
50
webpack.config.js
Normal file
@ -0,0 +1,50 @@
|
||||
/* global __dirname, require, module*/
|
||||
|
||||
const webpack = require('webpack');
|
||||
const UglifyJsPlugin = webpack.optimize.UglifyJsPlugin;
|
||||
const path = require('path');
|
||||
const env = require('yargs').argv.env; // use --env with webpack 2
|
||||
|
||||
let libraryName = 'ReGrid';
|
||||
|
||||
let plugins = [], outputFile;
|
||||
|
||||
if (env === 'build') {
|
||||
plugins.push(new UglifyJsPlugin({ minimize: true }));
|
||||
outputFile = libraryName + '.min.js';
|
||||
} else {
|
||||
outputFile = libraryName + '.js';
|
||||
}
|
||||
|
||||
const config = {
|
||||
entry: __dirname + '/src/index.js',
|
||||
devtool: 'source-map',
|
||||
output: {
|
||||
path: __dirname + '/lib',
|
||||
filename: outputFile,
|
||||
library: libraryName,
|
||||
libraryTarget: 'umd',
|
||||
umdNamedDefine: true
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /(\.jsx|\.js)$/,
|
||||
loader: 'babel-loader',
|
||||
exclude: /(node_modules|bower_components)/
|
||||
},
|
||||
{
|
||||
test: /(\.jsx|\.js)$/,
|
||||
loader: 'eslint-loader',
|
||||
exclude: /node_modules/
|
||||
}
|
||||
]
|
||||
},
|
||||
resolve: {
|
||||
modules: [path.resolve('./node_modules'), path.resolve('./src')],
|
||||
extensions: ['.json', '.js']
|
||||
},
|
||||
plugins: plugins
|
||||
};
|
||||
|
||||
module.exports = config;
|
||||
Loading…
x
Reference in New Issue
Block a user