diff --git a/.eslintignore b/.eslintignore index 62f10bcb9..6281f0315 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,5 +1,4 @@ -dist/*.js +dist/* demo/* spec/* -src/jquery.js -src/jquery-ui.js +src/jq/*.js diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 000000000..96d1e574f --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,23 @@ +module.exports = { + parser: '@typescript-eslint/parser', + env: { + browser: true, + commonjs: true, + es6: true, + node: true + }, + extends: [ + 'plugin:@typescript-eslint/recommended' + ], + parserOptions: { + ecmaVersion: 2020, + sourceType: 'module' + }, + rules: { + 'indent': ['error', 2], + 'max-len': ['error', 180], + 'no-trailing-spaces': 'error', + 'prefer-const': 0, + '@typescript-eslint/explicit-function-return-type': 0 + } +}; diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index e505744ea..000000000 --- a/.eslintrc.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "env": { - "browser": true, - "commonjs": true, - "es6": true, - "node": true - }, - "parserOptions": { - "ecmaFeatures": { - "jsx": true - }, - "sourceType": "module" - }, - "rules": { - "indent": ["error", 2], - "max-len": ["error", 180], - "camelcase": "error", - "no-trailing-spaces": "error" - } -} \ No newline at end of file diff --git a/.npmignore b/.npmignore index 86389a7f8..1536bd696 100644 --- a/.npmignore +++ b/.npmignore @@ -19,6 +19,8 @@ PULL_REQUEST_TEMPLATE.md freelancer karma.conf.js protractor.conf.js +tsconfig.json +webpack.config.js ## From .gitignore: *.log diff --git a/.vscode/settings.json b/.vscode/settings.json index 4e9faea3d..56337b8d4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,8 +10,8 @@ "dragstop", "dropover", "droppable", + "gridster", "gsresize", - "gsresizestop", "jqueryui", "resizestart" ] diff --git a/Gruntfile.js b/Gruntfile.js index a55471521..b1e6813cb 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,4 +1,3 @@ -/*eslint-disable camelcase */ module.exports = function(grunt) { grunt.loadNpmTasks('grunt-sass'); grunt.loadNpmTasks('grunt-contrib-cssmin'); @@ -16,7 +15,7 @@ module.exports = function(grunt) { sass: { options: { implementation: sass, - sourceMap: true + sourceMap: false }, dist: { files: { @@ -25,10 +24,10 @@ module.exports = function(grunt) { } } }, - cssmin: { dist: { options: { + sourceMap: false, keepSpecialComments: '*' }, files: { @@ -37,42 +36,39 @@ module.exports = function(grunt) { } } }, - copy: { dist: { files: { - 'dist/gridstack.js': ['src/gridstack.js'], - 'dist/gridstack.d.ts': ['src/gridstack.d.ts'], - 'dist/gridstack.jQueryUI.js': ['src/gridstack.jQueryUI.js'], 'dist/gridstack-poly.js': ['src/gridstack-poly.js'], - 'dist/jquery.js': ['src/jquery.js'], - 'dist/jquery-ui.js': ['src/jquery-ui.js'], + //'dist/jq/jquery.js': ['src/jq/jquery.js'], + //'dist/jq/jquery-ui.js': ['src/jq/jquery-ui.js'], 'dist/src/gridstack.scss': ['src/gridstack.scss'], 'dist/src/gridstack-extra.scss': ['src/gridstack-extra.scss'], } } }, - uglify: { options: { sourceMap: true, - sourceMapName: 'dist/gridstack.min.map', output: { comments: 'some' } }, dist: { files: { - 'dist/gridstack.min.js': ['src/gridstack.js'], - 'dist/gridstack.jQueryUI.min.js': ['src/gridstack.jQueryUI.js'], - 'dist/gridstack-poly.min.js': ['src/gridstack-poly.js'], - 'dist/jquery.min.js': ['src/jquery.js'], - 'dist/jquery-ui.min.js': ['src/jquery-ui.js'], - 'dist/gridstack.all.js': ['src/gridstack-poly.js', 'src/jquery.js', 'src/gridstack.js', 'src/jquery-ui.js', 'src/gridstack.jQueryUI.js'] + 'dist/jq/jquery.js': 'src/jq/jquery.js', + 'dist/jq/jquery-ui.js': 'src/jq/jquery-ui.js', + /* + 'dist/jq/gridstack-dd-jqueryui.min.js': 'dist/jq/gridstack-dd-jqueryui.js', + 'dist/gridstack-dd.min.js': 'dist/gridstack-dd.js', + 'dist/gridstack-engine.min.js': 'dist/gridstack-engine.js', + 'dist/gridstack-poly.min.js': 'src/gridstack-poly.js', + 'dist/types.min.js': 'dist/types.js', + 'dist/utils.min.js': 'dist/utils.js', + */ } } }, - eslint: { target: ['*.js', 'src/*.js'] }, @@ -80,7 +76,7 @@ module.exports = function(grunt) { watch: { scripts: { files: ['src/*.js'], - tasks: ['uglify', 'copy'], + tasks: ['copy', 'uglify'], options: { }, }, @@ -109,6 +105,7 @@ module.exports = function(grunt) { }, }, + // eslint-disable-next-line @typescript-eslint/camelcase protractor_webdriver: { all: { options: { @@ -119,7 +116,6 @@ module.exports = function(grunt) { }); grunt.registerTask('lint', ['eslint']); - grunt.registerTask('default', ['sass', 'cssmin', 'eslint', 'copy', 'uglify']); + grunt.registerTask('default', ['sass', 'cssmin', /*'eslint',*/ 'copy', 'uglify']); grunt.registerTask('e2e-test', ['connect', 'protractor_webdriver', 'protractor']); }; -/*eslint-enable camelcase */ \ No newline at end of file diff --git a/README.md b/README.md index ee545f248..0a9a09534 100644 --- a/README.md +++ b/README.md @@ -39,9 +39,10 @@ Join us on Slack: https://gridstackjs.troolee.com - [Custom columns CSS](#custom-columns-css) - [Override resizable/draggable options](#override-resizabledraggable-options) - [Touch devices support](#touch-devices-support) - - [Migrating to v0.6.x](#migrating-to-v06x) - - [Migrating to v1.0.0](#migrating-to-v100) + - [Migrating to v0.6](#migrating-to-v06) + - [Migrating to v1](#migrating-to-v1) - [jQuery Application](#jquery-application) + - [Migrating to v2](#migrating-to-v2) - [Changes](#changes) - [The Team](#the-team) @@ -71,89 +72,66 @@ npm install --save gridstack ## Include -```js -import 'gridstack/dist/gridstack.all.js'; -import 'gridstack/dist/gridstack.css'; -``` - -* when using webpack/ES6 imports you will need this instead (instead of all.js): +ES6 or Typescript ```js -import 'jquery'; -import 'jquery-ui'; - -import 'gridstack/dist/gridstack-poly'; // optional IE support -import GridStack from 'gridstack'; -import 'gridstack/dist/gridstack.jQueryUI'; +import { GridStack } from 'gridstack'; import 'gridstack/dist/gridstack.css'; ``` -If your project doesn't need to bring it's own jQuery (see [section](#jquery-application)) we include 3.5.1 that always export jQuery) -or jQuery-ui (we include a trimmed version with just drag&drop at 1/5th the size) -you can use the lightweight files provided by Gridstack instead. +legacy javascript. If you need to import individual files (see [jquery apps](#jquery-application) section) -either use full paths above ```js -import 'gridstack/dist/jquery'; -import 'gridstack/dist/jquery-ui'; +import 'gridstack/dist/gridstack.all.js'; +import 'gridstack/dist/gridstack.css'; ``` -or define an alias in your webpack configuration: -``` -module.exports = { - ... - resolve: { - alias: { - 'jquery': 'gridstack/dist/jquery.js', - 'jquery-ui': 'gridstack/dist/jquery-ui.js', - } - } -} -``` -* alternatively in html +alternatively in html ```html ``` -* or using CDN (minimized): +or using CDN (minimized): ```html - - + + ``` - - -if you need to debug, look at the git demo/ examples for non min includes. +.map files are included for debugging purposes. ## Basic usage creating items dynamically... -```html - - +```js +// ...in your HTML
- +// ...in your script +var grid = GridStack.init(); +grid.addWidget('
Item 1
', {width: 2}); +``` + +... or creating from list + +```js +// using serialize data instead of .addWidget() +const serializedData = [ + {x: 0, y: 0, width: 2, height: 2}, + {x: 2, y: 3, width: 3, height: 1}, + {x: 1, y: 3, width: 1, height: 1} +]; + +grid.load(serializedData); ``` ... or DOM created items -```html - - +```js +// ...in your HTML
Item 1
@@ -163,9 +141,8 @@ creating items dynamically...
- +// ...in your script +GridStack.init(); ``` see [jsfiddle sample](https://jsfiddle.net/adumesny/jqhkry7g) as running example too. @@ -189,7 +166,7 @@ GridStack.prototype.printCount = function() { console.log('grid has ' + this.engine.nodes.length + ' items'); }; -var grid = GridStack.init(); +let grid = GridStack.init(); // you can now call grid.printCount(); @@ -216,7 +193,7 @@ GridStack.init( {column: N} ); 2) include `gridstack-extra.css` if **N < 12** (else custom CSS - see next). Without these, things will not render/work correctly. ```html - +
...
``` @@ -313,7 +290,7 @@ working on touch-based devices. Also `alwaysShowResizeHandle` option may be useful: ```js -var options = { +let options = { alwaysShowResizeHandle: /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) }; GridStack.init(options); @@ -322,17 +299,17 @@ GridStack.init(options); If you're still experiencing issues on touch devices please check [#444](https://github.com/gridstack/gridstack.js/issues/444) -## Migrating to v0.6.x +## Migrating to v0.6 starting in 0.6.x `change` event are no longer sent (for pretty much most nodes!) when an item is just added/deleted unless it also changes other nodes (was incorrect and causing inefficiencies). You may need to track `added|removed` [events](https://github.com/gridstack/gridstack.js/tree/develop/doc#events) if you didn't and relied on the old broken behavior. -## Migrating to v1.0.0 +## Migrating to v1 v1.0.0 removed Jquery from the API and external dependencies, which will require some code changes. Here is a list of the changes: -1. see [Migrating to v0.6.x](#migrating-to-v06x) if you didn't already +1. see [Migrating to v0.6](#migrating-to-v06) if you didn't already -2. your code only needs to include `gridstack.all.js` and `gristack.css` (don't include other JS) and is recommended you do that as internal dependencies will change over time. If you are jquery based, also see note below. +2. your code only needs to include `gridstack.all.js` and `gristack.css` (don't include other JS) and is recommended you do that as internal dependencies will change over time. If you are jquery based, see [jquery app](#jquery-application) below. 3. code change: @@ -353,7 +330,7 @@ var grid = $('.grid-stack').data('gridstack'); **NEW** ```js // element identifier defaults to '.grid-stack', returns the grid -// Note: for Typescript use window.GridStack.init() until next native TS version +// Note: for Typescript use window.GridStack.init() until next native 2.x TS version var grid = GridStack.init(opts?, element?); // returns DOM element @@ -365,7 +342,7 @@ grid.on('added', function(e, items) {/* items contains info */}); // grid access after init var grid = el.gridstack; // where el = document.querySelector('.grid-stack') or other ways... ``` -Other vars/global changes +Other changes ``` `GridStackUI` --> `GridStack` `GridStackUI.GridStackEngine` --> `GridStack.Engine` @@ -378,7 +355,29 @@ Recommend looking at the [many samples](./demo) for more code examples. ### jQuery Application -We're working on implementing HTML5 drag'n'drop through the plugin system. Right now it is still jquery-ui based. Because of that we are still bundling `jquery` (3.5.1) + `jquery-ui` (1.12.1 minimal drag|drop|resize) internally in `gridstack.all.js`. IFF your app needs to bring your own version instead, you should **instead** include `gridstack-poly.min.js` (optional IE support) + `gridstack.min.js` + `gridstack.jQueryUI.min.js` after you import your JQ libs. +We're working on implementing HTML5 drag'n'drop through the plugin system. Right now it is still jquery-ui based. Because of that we are still bundling `jquery` (3.5.1) + `jquery-ui` (1.12.1 minimal drag|drop|resize) internally in `gridstack.all.js`. IFF your app needs to bring your own version instead, you should **instead** include `gridstack-poly.min.js` (optional IE support) + `gridstack.min.js` + `gridstack.jQueryUI.min.js` after you import your JQ libs. But note that there are issue with jQuery and ES6 import (see [1306](https://github.com/gridstack/gridstack.js/issues/1306)). + +Note: v2.0.-rc does not currently support importing GridStack Drag&Drop without also including our jquery + jqueryui. Still trying to figure how to make that bundle possible. + +## Migrating to v2 + +make sure to read v1 migration first! + +v2.x is a Typescript rewrite of 1.x, removing all jquery events, using classes and overall code cleanup to support ES6 modules. Your code might need to change from 1.x + +1. In general methods that used no args (getter) vs setter can't be used in TS when the arguments differ (set/get are also not function calls so API would have changed). Instead we decided to have all set methods return `GridStack` to they can be chain-able (ex: `grid.float(true).cellHeight(10).column(6)`). Also legacy methods that used to take many parameters will now take a single object (typically `GridstackOptions` or `GridStackWidget`). + +``` +`addWidget(el, x, y, width, height)` --> `addWidget(el, {with: 2})` +`float()` to get value --> `getFloat()` +'cellHeight()` to get value --> `getCellHeight()` +'verticalMargin' is now 'margin' grid options and API that applies to all 4 sides. +'verticalMargin()` to get value --> `getMargin()` +``` + +2. event signatures are generic and not jquery-ui dependent anymore. `gsresizestop` has been removed as `resizestop|dragstop` are now called **after** the DOM attributes have been updated. + +3. `oneColumnMode` would trigger when `window.width` < 768px by default. We now check for grid width instead (more correct and supports nesting). You might need to adjust grid `minWidth` or `disableOneColumnMode`. Changes ===== diff --git a/demo/advance.html b/demo/advance.html index ec71a386e..d90cee5a2 100644 --- a/demo/advance.html +++ b/demo/advance.html @@ -13,10 +13,7 @@ - - - - + + + +
@@ -23,27 +28,22 @@

Float grid demo



- + diff --git a/demo/knockout.html b/demo/knockout.html index 1021503a2..2fdbb23a3 100644 --- a/demo/knockout.html +++ b/demo/knockout.html @@ -9,11 +9,7 @@ - - - - - +
@@ -29,8 +25,8 @@

knockout.js Demo

ko.components.register('dashboard-grid', { viewModel: { createViewModel: function (controller, componentInfo) { - var ViewModel = function (controller, componentInfo) { - var grid = null; + let ViewModel = function (controller, componentInfo) { + let grid = null; this.widgets = controller.widgets; @@ -39,7 +35,7 @@

knockout.js Demo

grid = GridStack.init({auto: false}); } - var item = items.find(function (i) { return i.nodeType == 1 }); + let item = items.find(function (i) { return i.nodeType == 1 }); grid.addWidget(item); ko.utils.domNodeDisposal.addDisposeCallback(item, function () { grid.removeWidget(item); @@ -60,8 +56,8 @@

knockout.js Demo

].join('') }); - var Controller = function (widgets) { - var self = this; + let Controller = function (widgets) { + let self = this; this.widgets = ko.observableArray(widgets); @@ -82,14 +78,14 @@

knockout.js Demo

}; }; - var widgets = [ + let widgets = [ {x: 0, y: 0, width: 2, height: 2, id: '0'}, {x: 2, y: 0, width: 4, height: 2, id: '1'}, {x: 6, y: 0, width: 2, height: 4, id: '2'}, {x: 1, y: 2, width: 4, height: 2, id: '3'} ]; - var controller = new Controller(widgets); + let controller = new Controller(widgets); ko.applyBindings(controller); diff --git a/demo/experiment/locked.html b/demo/locked.html similarity index 81% rename from demo/experiment/locked.html rename to demo/locked.html index 05576ff65..92cb4d033 100644 --- a/demo/experiment/locked.html +++ b/demo/locked.html @@ -6,11 +6,8 @@ Locked demo - - - - - + + @@ -25,25 +22,25 @@

Locked demo

- - - - + - - - - - +
@@ -34,8 +30,8 @@

RTL Demo

ko.components.register('dashboard-grid', { viewModel: { createViewModel: function (controller, componentInfo) { - var ViewModel = function (controller, componentInfo) { - var grid = null; + let ViewModel = function (controller, componentInfo) { + let grid = null; this.widgets = controller.widgets; @@ -44,7 +40,7 @@

RTL Demo

grid = GridStack.init({auto: false}); } - var item = items.find(function (i) { return i.nodeType == 1 }); + let item = items.find(function (i) { return i.nodeType == 1 }); grid.addWidget(item); ko.utils.domNodeDisposal.addDisposeCallback(item, function () { grid.removeWidget(item); @@ -65,8 +61,8 @@

RTL Demo

].join('') }); - var Controller = function (widgets) { - var self = this; + let Controller = function (widgets) { + let self = this; this.widgets = ko.observableArray(widgets); @@ -88,14 +84,14 @@

RTL Demo

}; }; - var widgets = [ + let widgets = [ {x: 0, y: 0, width: 2, height: 2, index: 1}, {x: 2, y: 0, width: 4, height: 2, index: 2}, {x: 6, y: 0, width: 2, height: 4, index: 3}, {x: 1, y: 2, width: 4, height: 2, index: 4} ]; - var controller = new Controller(widgets); + let controller = new Controller(widgets); ko.applyBindings(controller); diff --git a/demo/serialization.html b/demo/serialization.html index b60f8ade6..688ec78c9 100644 --- a/demo/serialization.html +++ b/demo/serialization.html @@ -7,34 +7,32 @@ Serialization demo - - - - - +

Serialization demo

Save Load + Save Manual + Load Manual Clear

-
+