Full Mobile Support
++ Craft responsive, mobile-friendly applications with ease. +
+diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..4e357c348 --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +coverage +dist +dist_save +*.tgz +*.zip +angular/ +!angular/doc/ +!angular/doc/html/ +!angular/doc/html/media/ +react/ +.DS_Store +doc/.DS_Store + +!node_modules/ +node_modules/* +!node_modules/gridstack/ +node_modules/gridstack/* +!node_modules/gridstack/dist/ +node_modules/gridstack/dist/* +!node_modules/gridstack/dist/gridstack-all.js +!node_modules/gridstack/dist/gridstack-all.js.map +!node_modules/gridstack/dist/gridstack.css +!node_modules/gridstack/dist/gridstack.min.css diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 000000000..e69de29bb diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000..d805d4e0e --- /dev/null +++ b/.prettierignore @@ -0,0 +1,3 @@ +./demo +./logo +**/node_modules \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 000000000..66e7e941c --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,6 @@ +{ + "trailingComma": "es5", + "tabWidth": 2, + "semi": false, + "singleQuote": true +} \ No newline at end of file diff --git a/CNAME b/CNAME new file mode 100644 index 000000000..3530eb4f0 --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +gridstackjs.com \ No newline at end of file diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 511ea0819..000000000 --- a/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Pavel Reznikov - -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. - diff --git a/README.md b/README.md index e0460911b..a1b5993c1 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,34 @@ -gridstack.js -============ +# Gridstack Website -gridstack.js is a jQuery plugin for widget layout +## Technos +### Icons +- Lucide Icons +> We use Lucide Icons for the website, but we copy svg instead of using the lib directly. You can find them [here](https://lucide.dev/) +- Dev icons +(We use the link for now but will be replaced by svg) +> We use Dev icons for the website, but we copy svg instead of using the lib directly. You can find them [here](https://devicon.dev/) +### Gridstack +(Of course 🙃) +### Highlight.js +For code highlighting, used in the homepage to have a beautiful code snippet `
...`
+A custom theme is used, you can find it in the `src/styles/highlight.css` file
+### Dev dependencies
+- Prettier
+For code formatting
+
+
+> The tailwind.config.js file is useless but make code editor plugins works.
+### Roadmap
+
+- [ ] Create a beautiful examples/ page
+- [ ] Create a beautiful documentation/ page
+- [ ] Create a beautiful changes/ page
+- [ ] Improve demo.css to follow the same style as the website
+- [ ] Create a layout in the examples/[name.html] to switch easily between examples
+- [ ] Add micro-interactions to the website
+- [ ] Add animation to mobile navbar
+- [x] Add lucide icons to the website & in many sections
+- [ ] Improve SEO with meta tags on each page
+- [ ] Find a way to update automatically `Current version | v10.1.2`
+- [ ] Improve responsive design (mobile version) by changing grid to 6 columns instead of 12 for example and reduce padding on x, etc.
+- [ ] Fix advanced demo "Add widget" to not impact the background & fix margins when dropped in the grid
\ No newline at end of file
diff --git a/angular/doc/html/.nojekyll b/angular/doc/html/.nojekyll
new file mode 100644
index 000000000..e2ac6616a
--- /dev/null
+++ b/angular/doc/html/.nojekyll
@@ -0,0 +1 @@
+TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false.
\ No newline at end of file
diff --git a/angular/doc/html/assets/hierarchy.js b/angular/doc/html/assets/hierarchy.js
new file mode 100644
index 000000000..fb85f0adc
--- /dev/null
+++ b/angular/doc/html/assets/hierarchy.js
@@ -0,0 +1 @@
+window.hierarchyData = "eJyrVirKzy8pVrKKjtVRKkpNy0lNLsnMzytWsqqurQUAmx4Kpg=="
\ No newline at end of file
diff --git a/angular/doc/html/assets/highlight.css b/angular/doc/html/assets/highlight.css
new file mode 100644
index 000000000..08c38c277
--- /dev/null
+++ b/angular/doc/html/assets/highlight.css
@@ -0,0 +1,148 @@
+:root {
+ --light-hl-0: #800000;
+ --dark-hl-0: #808080;
+ --light-hl-1: #CD3131;
+ --dark-hl-1: #F44747;
+ --light-hl-2: #000000;
+ --dark-hl-2: #D4D4D4;
+ --light-hl-3: #E50000;
+ --dark-hl-3: #9CDCFE;
+ --light-hl-4: #0000FF;
+ --dark-hl-4: #CE9178;
+ --light-hl-5: #AF00DB;
+ --dark-hl-5: #C586C0;
+ --light-hl-6: #A31515;
+ --dark-hl-6: #CE9178;
+ --light-hl-7: #800000;
+ --dark-hl-7: #D7BA7D;
+ --light-hl-8: #0451A5;
+ --dark-hl-8: #CE9178;
+ --light-hl-9: #001080;
+ --dark-hl-9: #9CDCFE;
+ --light-hl-10: #795E26;
+ --dark-hl-10: #DCDCAA;
+ --light-hl-11: #008000;
+ --dark-hl-11: #6A9955;
+ --light-hl-12: #0000FF;
+ --dark-hl-12: #569CD6;
+ --light-hl-13: #267F99;
+ --dark-hl-13: #4EC9B0;
+ --light-hl-14: #098658;
+ --dark-hl-14: #B5CEA8;
+ --light-hl-15: #800000;
+ --dark-hl-15: #569CD6;
+ --light-hl-16: #000000;
+ --dark-hl-16: #C8C8C8;
+ --light-hl-17: #0070C1;
+ --dark-hl-17: #4FC1FF;
+ --light-code-background: #FFFFFF;
+ --dark-code-background: #1E1E1E;
+}
+
+@media (prefers-color-scheme: light) { :root {
+ --hl-0: var(--light-hl-0);
+ --hl-1: var(--light-hl-1);
+ --hl-2: var(--light-hl-2);
+ --hl-3: var(--light-hl-3);
+ --hl-4: var(--light-hl-4);
+ --hl-5: var(--light-hl-5);
+ --hl-6: var(--light-hl-6);
+ --hl-7: var(--light-hl-7);
+ --hl-8: var(--light-hl-8);
+ --hl-9: var(--light-hl-9);
+ --hl-10: var(--light-hl-10);
+ --hl-11: var(--light-hl-11);
+ --hl-12: var(--light-hl-12);
+ --hl-13: var(--light-hl-13);
+ --hl-14: var(--light-hl-14);
+ --hl-15: var(--light-hl-15);
+ --hl-16: var(--light-hl-16);
+ --hl-17: var(--light-hl-17);
+ --code-background: var(--light-code-background);
+} }
+
+@media (prefers-color-scheme: dark) { :root {
+ --hl-0: var(--dark-hl-0);
+ --hl-1: var(--dark-hl-1);
+ --hl-2: var(--dark-hl-2);
+ --hl-3: var(--dark-hl-3);
+ --hl-4: var(--dark-hl-4);
+ --hl-5: var(--dark-hl-5);
+ --hl-6: var(--dark-hl-6);
+ --hl-7: var(--dark-hl-7);
+ --hl-8: var(--dark-hl-8);
+ --hl-9: var(--dark-hl-9);
+ --hl-10: var(--dark-hl-10);
+ --hl-11: var(--dark-hl-11);
+ --hl-12: var(--dark-hl-12);
+ --hl-13: var(--dark-hl-13);
+ --hl-14: var(--dark-hl-14);
+ --hl-15: var(--dark-hl-15);
+ --hl-16: var(--dark-hl-16);
+ --hl-17: var(--dark-hl-17);
+ --code-background: var(--dark-code-background);
+} }
+
+:root[data-theme='light'] {
+ --hl-0: var(--light-hl-0);
+ --hl-1: var(--light-hl-1);
+ --hl-2: var(--light-hl-2);
+ --hl-3: var(--light-hl-3);
+ --hl-4: var(--light-hl-4);
+ --hl-5: var(--light-hl-5);
+ --hl-6: var(--light-hl-6);
+ --hl-7: var(--light-hl-7);
+ --hl-8: var(--light-hl-8);
+ --hl-9: var(--light-hl-9);
+ --hl-10: var(--light-hl-10);
+ --hl-11: var(--light-hl-11);
+ --hl-12: var(--light-hl-12);
+ --hl-13: var(--light-hl-13);
+ --hl-14: var(--light-hl-14);
+ --hl-15: var(--light-hl-15);
+ --hl-16: var(--light-hl-16);
+ --hl-17: var(--light-hl-17);
+ --code-background: var(--light-code-background);
+}
+
+:root[data-theme='dark'] {
+ --hl-0: var(--dark-hl-0);
+ --hl-1: var(--dark-hl-1);
+ --hl-2: var(--dark-hl-2);
+ --hl-3: var(--dark-hl-3);
+ --hl-4: var(--dark-hl-4);
+ --hl-5: var(--dark-hl-5);
+ --hl-6: var(--dark-hl-6);
+ --hl-7: var(--dark-hl-7);
+ --hl-8: var(--dark-hl-8);
+ --hl-9: var(--dark-hl-9);
+ --hl-10: var(--dark-hl-10);
+ --hl-11: var(--dark-hl-11);
+ --hl-12: var(--dark-hl-12);
+ --hl-13: var(--dark-hl-13);
+ --hl-14: var(--dark-hl-14);
+ --hl-15: var(--dark-hl-15);
+ --hl-16: var(--dark-hl-16);
+ --hl-17: var(--dark-hl-17);
+ --code-background: var(--dark-code-background);
+}
+
+.hl-0 { color: var(--hl-0); }
+.hl-1 { color: var(--hl-1); }
+.hl-2 { color: var(--hl-2); }
+.hl-3 { color: var(--hl-3); }
+.hl-4 { color: var(--hl-4); }
+.hl-5 { color: var(--hl-5); }
+.hl-6 { color: var(--hl-6); }
+.hl-7 { color: var(--hl-7); }
+.hl-8 { color: var(--hl-8); }
+.hl-9 { color: var(--hl-9); }
+.hl-10 { color: var(--hl-10); }
+.hl-11 { color: var(--hl-11); }
+.hl-12 { color: var(--hl-12); }
+.hl-13 { color: var(--hl-13); }
+.hl-14 { color: var(--hl-14); }
+.hl-15 { color: var(--hl-15); }
+.hl-16 { color: var(--hl-16); }
+.hl-17 { color: var(--hl-17); }
+pre, code { background: var(--code-background); }
diff --git a/angular/doc/html/assets/icons.js b/angular/doc/html/assets/icons.js
new file mode 100644
index 000000000..58882d76d
--- /dev/null
+++ b/angular/doc/html/assets/icons.js
@@ -0,0 +1,18 @@
+(function() {
+ addIcons();
+ function addIcons() {
+ if (document.readyState === "loading") return document.addEventListener("DOMContentLoaded", addIcons);
+ const svg = document.body.appendChild(document.createElementNS("http://www.w3.org/2000/svg", "svg"));
+ svg.innerHTML = `AbstractOverride this method to return serializable data for this widget.
+Return an object with properties that map to your component's @Input() fields. +The selector is handled automatically, so only include component-specific data.
+Object containing serializable component data
+Override this method to handle widget restoration from saved data.
+Use this for complex initialization that goes beyond simple @Input() mapping. +The default implementation automatically assigns input data to component properties.
+The saved widget data including input properties
+Angular component wrapper for individual GridStack items.
+This component represents a single grid item and handles:
+Use in combination with GridstackComponent for the parent grid.
+return the latest grid options (from GS once built, otherwise initial values)
+return the native element that contains grid specific fields as well
+clears the initial options now that we've built
+A callback method that performs custom clean-up, invoked immediately +before a directive, pipe, or service instance is destroyed.
+OptionalcontainerContainer for dynamic component creation within this grid item. +Used to append child components programmatically.
+Component reference for dynamic component removal. +Used internally when this component is created dynamically.
+Reference to child widget component for serialization. +Used to save/restore additional data along with grid position.
+Protected Optional_Protected ReadonlyelementAngular component wrapper for GridStack.
+This component provides Angular integration for GridStack grids, handling:
+Use in combination with GridstackItemComponent for individual grid items.
+Get the current running grid options
+Get the native DOM element that contains grid-specific fields. +This element has GridStack properties attached to it.
+StaticaddStaticgetExtract the selector string from an Angular component type.
+The component type to get selector from
+The component's selector string
+A callback method that is invoked immediately after the +default change detector has checked the directive's +data-bound properties for the first time, +and before any of the view or content children have been checked. +It is invoked only once when the directive is instantiated.
+wait until after all DOM is ready to init gridstack children (after angular ngFor and sub-components run first)
+A callback method that performs custom clean-up, invoked immediately +before a directive, pipe, or service instance is destroyed.
+called when the TEMPLATE (not recommended) list of items changes - get a list of nodes and +update the layout accordingly (which will take care of adding/removing items changed by Angular)
+check if the grid is empty, if so show alternative content
+Protectedhookget all known events as easy to use Outputs for convenience
+Optionalgrid: GridStackProtectedunhookOptionalgrid: GridStackOptionalgridstackList of template-based grid items (not recommended approach). +Used to sync between DOM and GridStack internals when items are defined in templates. +Prefer dynamic component creation instead.
+OptionalcontainerContainer for dynamic component creation (recommended approach). +Used to append grid items programmatically at runtime.
+OptionalisControls whether empty content should be displayed. +Set to true to show ng-content with 'empty-content' selector when grid has no items.
+Emitted when widgets are added to the grid
+Emitted when grid layout changes
+Emitted when grid is disabled
+Emitted during widget drag operations
+Emitted when widget drag starts
+Emitted when widget drag stops
+Emitted when widget is dropped
+Emitted when grid is enabled
+Emitted when widgets are removed from the grid
+Emitted during widget resize operations
+Emitted when widget resize starts
+Emitted when widget resize stops
+Component reference for dynamic component removal. +Used internally when this component is created dynamically.
+StaticselectorMapping of component selectors to their types for dynamic creation.
+This enables dynamic component instantiation from string selectors. +Angular doesn't provide public access to this mapping, so we maintain our own.
+Protected Optional_Protected Optional_Protected_Protected OptionalloadedProtected ReadonlyelementUse GridstackComponent and GridstackItemComponent as standalone components instead.
+This NgModule is provided for backward compatibility but is no longer the recommended approach. +Import components directly in your standalone components or use the new Angular module structure.
+// Preferred approach - standalone components
@Component({
selector: 'my-app',
imports: [GridstackComponent, GridstackItemComponent],
template: '<gridstack></gridstack>'
})
export class AppComponent {}
// Legacy approach (deprecated)
@NgModule({
imports: [GridstackModule]
})
export class AppModule {}
+
+
+can be used when a new item needs to be created, which we do as a Angular component, or deleted (skip)
+called for each item in the grid - check if additional information needs to be saved. +Note: since this is options minus gridstack protected members using Utils.removeInternalForSave(), +this typically doesn't need to do anything. However your custom Component @Input() are now supported +using BaseWidget.serialize()
+track when widgeta re updated (rather than created) to make sure we de-serialize them as well
+The Angular wrapper component
Running version can be seen here https://stackblitz.com/edit/gridstack-angular
+this is the recommended way if you are going to have multiple grids (alow drag&drop between) or drag from toolbar to create items, or drag to remove items, etc...
+I.E. don't use Angular templating to create grid items as that is harder to sync when gridstack will also add/remove items.
+MyComponent HTML
+<gridstack [options]="gridOptions"></gridstack>
+
+
+MyComponent CSS
+@import "gridstack/dist/gridstack.min.css";
.grid-stack {
background: #fafad2;
}
.grid-stack-item-content {
text-align: center;
background-color: #18bc9c;
}
+
+
+Standalone MyComponent Code
+import { GridStackOptions } from 'gridstack';
import { GridstackComponent, GridstackItemComponent } from 'gridstack/dist/angular';
@Component({
imports: [ // SKIP if doing module import instead (next)
GridstackComponent,
GridstackItemComponent
]
...
})
export class MyComponent {
// sample grid options + items to load...
public gridOptions: GridStackOptions = {
margin: 5,
children: [ // or call load(children) or addWidget(children[0]) with same data
{x:0, y:0, minW:2, content:'Item 1'},
{x:1, y:0, content:'Item 2'},
{x:0, y:1, content:'Item 3'},
]
}
}
+
+
+IF doing module import instead of standalone, you will also need this:
+import { GridstackModule } from 'gridstack/dist/angular';
@NgModule({
imports: [GridstackModule, ...]
...
bootstrap: [AppComponent]
})
export class AppModule { }
+
+
+In this example (build on previous one) will use your actual custom angular components inside each grid item (instead of dummy html content) and have per component saved settings as well (using BaseWidget).
+HTML
+<gridstack [options]="gridOptions" (changeCB)="onChange($event)">
<div empty-content>message when grid is empty</div>
</gridstack>
+
+
+Code
+import { Component } from '@angular/core';
import { GridStack, GridStackOptions } from 'gridstack';
import { GridstackComponent, gsCreateNgComponents, NgGridStackWidget, nodesCB, BaseWidget } from 'gridstack/dist/angular';
// some custom components
@Component({
selector: 'app-a',
template: 'Comp A {{text}}',
})
export class AComponent extends BaseWidget implements OnDestroy {
@Input() text: string = 'foo'; // test custom input data
public override serialize(): NgCompInputs | undefined { return this.text ? {text: this.text} : undefined; }
ngOnDestroy() {
console.log('Comp A destroyed'); // test to make sure cleanup happens
}
}
@Component({
selector: 'app-b',
template: 'Comp B',
})
export class BComponent extends BaseWidget {
}
// ...in your module (classic), OR your ng19 app.config provideEnvironmentInitializer call this:
constructor() {
// register all our dynamic components types created by the grid
GridstackComponent.addComponentToSelectorType([AComponent, BComponent]) ;
}
// now our content will use Components instead of dummy html content
public gridOptions: NgGridStackOptions = {
margin: 5,
minRow: 1, // make space for empty message
children: [ // or call load()/addWidget() with same data
{x:0, y:0, minW:2, selector:'app-a'},
{x:1, y:0, minW:2, selector:'app-a', input: { text: 'bar' }}, // custom input that works using BaseWidget.deserialize() Object.assign(this, w.input)
{x:2, y:0, selector:'app-b'},
{x:3, y:0, content:'plain html'},
]
}
// called whenever items change size/position/etc.. see other events
public onChange(data: nodesCB) {
console.log('change ', data.nodes.length > 1 ? data.nodes : data.nodes[0]);
}
+
+
+For simple case where you control the children creation (gridstack doesn't do create or re-parenting)
+HTML
+<gridstack [options]="gridOptions" (changeCB)="onChange($event)">
<!-- Angular 17+ -->
@for (n of items; track n.id) {
<gridstack-item [options]="n">Item {{n.id}}</gridstack-item>
}
<!-- Angular 16 -->
<gridstack-item *ngFor="let n of items; trackBy: identify" [options]="n"> Item {{n.id}} </gridstack-item>
</gridstack>
+
+
+Code
+import { GridStackOptions, GridStackWidget } from 'gridstack';
import { nodesCB } from 'gridstack/dist/angular';
/** sample grid options and items to load... */
public gridOptions: GridStackOptions = { margin: 5 }
public items: GridStackWidget[] = [
{x:0, y:0, minW:2, id:'1'}, // must have unique id used for trackBy
{x:1, y:0, id:'2'},
{x:0, y:1, id:'3'},
];
// called whenever items change size/position/etc..
public onChange(data: nodesCB) {
console.log('change ', data.nodes.length > 1 ? data.nodes : data.nodes[0]);
}
// ngFor unique node id to have correct match between our items used and GS
public identify(index: number, w: GridStackWidget) {
return w.id; // or use index if no id is set and you only modify at the end...
}
+
+
+You can see a fuller example at app.component.ts
+to build the demo, go to angular/projects/demo and run yarn + yarn start and navigate to http://localhost:4200/
Code started shipping with v8.1.2+ in dist/angular for people to use directly and is an angular module! (source code under dist/angular/src)
createComponent() API and Standalone Components (verified against 19+)NOTE: if you are on Angular 13 or below: copy the wrapper code over (or patch it - see main page example) and change createComponent() calls to use old API instead:
+NOTE2: now that we're using standalone, you will also need to remove standalone: true and imports on each component so you will to copy those locally (or use <11.1.2 version)
protected resolver: ComponentFactoryResolver,
...
const factory = this.resolver.resolveComponentFactory(GridItemComponent);
const gridItemRef = grid.container.createComponent(factory) as ComponentRef<GridItemComponent>;
// ...do the same for widget selector...
+
+
+GridstackItemComponent.option directly - see modifyNgFor() example.Would appreciate getting help doing the same for React and Vue (2 other popular frameworks)
+-Alain
+Extended HTMLElement interface for grid items. +Stores a back-reference to the Angular component for integration.
+Optionaloptions: GetAnimationsOptionsInserts nodes just after node, while replacing strings in nodes with equivalent Text nodes.
+Throws a "HierarchyRequestError" DOMException if the constraints of the node tree are violated.
+Inserts nodes just before node, while replacing strings in nodes with equivalent Text nodes.
+Throws a "HierarchyRequestError" DOMException if the constraints of the node tree are violated.
+Removes node.
+Replaces node with nodes, while replacing strings in nodes with equivalent Text nodes.
+Throws a "HierarchyRequestError" DOMException if the constraints of the node tree are violated.
+Creates a shadow root for element and returns it.
+Optionaloptions: CheckVisibilityOptionsReturns element's first attribute whose qualified name is qualifiedName, and null if there is no such attribute otherwise.
+Returns element's attribute whose namespace is namespace and local name is localName, and null if there is no such attribute otherwise.
+Returns the qualified names of all element's attributes. Can contain duplicates.
+Returns a HTMLCollection of the elements in the object on which the method was invoked (a document or an element) that have all the classes given by classNames. The classNames argument is interpreted as a space-separated list of classes.
+Returns true if element has an attribute whose qualified name is qualifiedName, and false otherwise.
+Returns true if element has an attribute whose namespace is namespace and local name is localName.
+Returns true if element has attributes, and false otherwise.
+Returns true if matching selectors against element's root yields element, and false otherwise.
+Removes element's first attribute whose qualified name is qualifiedName.
+Removes element's attribute whose namespace is namespace and local name is localName.
+Displays element fullscreen and resolves promise when done.
+When supplied, options's navigationUI member indicates whether showing navigation UI while in fullscreen is preferred or not. If set to "show", navigation simplicity is preferred over screen space, and if set to "hide", more screen space is preferred. User agents are always free to honor user preference over the application's. The default value "auto" indicates no application preference.
+Optionaloptions: FullscreenOptionsOptionaloptions: ScrollToOptionsOptionaloptions: ScrollToOptionsOptionalarg: boolean | ScrollIntoViewOptionsOptionaloptions: ScrollToOptionsSets the value of element's first attribute whose qualified name is qualifiedName to value.
+If force is not given, "toggles" qualifiedName, removing it if it is present and adding it if it is not present. If force is true, adds qualifiedName. If force is false, removes qualifiedName.
+Returns true if qualifiedName is now present, and false otherwise.
+Optionalforce: booleanDispatches a synthetic event event to target and returns true if either event's cancelable attribute value is false or its preventDefault() method was not invoked, and false otherwise.
+Optionaloptions: FocusOptionsReturns a copy of node. If deep is true, the copy also includes the node's descendants.
+Optionaldeep: booleanReturns a bitmask indicating the position of other relative to node.
+Returns true if other is an inclusive descendant of node, and false otherwise.
+Returns node's root.
+Optionaloptions: GetRootNodeOptionsReturns whether node has children.
+Returns whether node and otherNode have the same properties.
+Removes empty exclusive Text nodes and concatenates the data of remaining contiguous exclusive Text nodes into the first of their nodes.
+Inserts nodes after the last child of node, while replacing strings in nodes with equivalent Text nodes.
+Throws a "HierarchyRequestError" DOMException if the constraints of the node tree are violated.
+Inserts nodes before the first child of node, while replacing strings in nodes with equivalent Text nodes.
+Throws a "HierarchyRequestError" DOMException if the constraints of the node tree are violated.
+Replace all children of node with nodes, while replacing strings in nodes with equivalent Text nodes.
+Throws a "HierarchyRequestError" DOMException if the constraints of the node tree are violated.
+Optional_Back-reference to the Angular GridStackItem component
+ReadonlyattributesReadonlyclassAllows for manipulation of element's class content attribute as a set of whitespace-separated tokens through a DOMTokenList object.
+Returns the value of element's class content attribute. Can be set to change it.
+ReadonlyclientReadonlyclientReadonlyclientReadonlyclientReturns the value of element's id content attribute. Can be set to change it.
+ReadonlylocalReturns the local name.
+ReadonlynamespaceReturns the namespace.
+ReadonlyownerReturns the node document. Returns null for documents.
+ReadonlypartReadonlyprefixReturns the namespace prefix.
+ReadonlyscrollReadonlyscrollReadonlyshadowReturns element's shadow root, if any, and if shadow root's mode is "open", and null otherwise.
+Returns the value of element's slot content attribute. Can be set to change it.
+ReadonlytagReturns the HTML-uppercased qualified name.
+ReadonlystyleReadonlyisFires when the user aborts the download.
+Fires when the object loses the input focus.
+Occurs when playback is possible, but would require further buffering.
+Fires when the contents of the object or selection have changed.
+Fires when the user clicks the left mouse button on the object
+Fires when the user clicks the right mouse button in the client area, opening the context menu.
+Fires when the user double-clicks the object.
+Fires on the source object continuously during a drag operation.
+Fires on the source object when the user releases the mouse at the close of a drag operation.
+Fires on the target element when the user drags the object to a valid drop target.
+Fires on the target object when the user moves the mouse out of a valid drop target during a drag operation.
+Fires on the target element continuously while the user drags the object over a valid drop target.
+Fires on the source object when the user starts to drag a text selection or selected object.
+Occurs when the duration attribute is updated.
+Occurs when the media element is reset to its initial state.
+Occurs when the end of playback is reached.
+Fires when an error occurs during object loading.
+Fires when the object receives focus.
+Fires when the user presses a key.
+Fires when the user presses an alphanumeric key.
+Fires when the user releases a key.
+Fires immediately after the browser loads the object.
+Occurs when media data is loaded at the current playback position.
+Occurs when the duration and dimensions of the media have been determined.
+Occurs when Internet Explorer begins looking for media data.
+Fires when the user clicks the object with either mouse button.
+Fires when the user moves the mouse over the object.
+Fires when the user moves the mouse pointer outside the boundaries of the object.
+Fires when the user moves the mouse pointer into the object.
+Fires when the user releases a mouse button while the mouse is over the object.
+Occurs when playback is paused.
+Occurs when the play method is requested.
+Occurs when the audio or video has started playing.
+Occurs to indicate progress while downloading media data.
+Occurs when the playback rate is increased or decreased.
+Fires when the user resets a form.
+Fires when the user repositions the scroll box in the scroll bar on the object.
+Occurs when the seek operation ends.
+Occurs when the current playback position is moved.
+Fires when the current selection changes.
+Occurs when the download has stopped.
+Occurs if the load operation has been intentionally halted.
+Occurs to indicate the current playback position.
+OptionalontouchcancelOptionalontouchendOptionalontouchmoveOptionalontouchstartOccurs when the volume is changed, or playback is muted or unmuted.
+Occurs when playback stops because the next frame of a video resource is not available.
+ReadonlyaccessReadonlyoffsetReadonlyoffsetReadonlyoffsetReadonlyoffsetReadonlyoffsetReadonlydatasetOptionalnonceReadonlybaseReturns node's node document's document base URL.
+ReadonlychildReturns the children.
+ReadonlyfirstReturns the first child.
+ReadonlyisReturns true if node is connected and false otherwise.
+ReadonlylastReturns the last child.
+ReadonlynextReturns the next sibling.
+ReadonlynodeReturns a string appropriate for the type of node.
+ReadonlynodeReturns the type of node.
+ReadonlyparentReturns the parent element.
+ReadonlyparentReturns the parent.
+ReadonlypreviousReturns the previous sibling.
+ReadonlyELEMENT_node is an element.
+ReadonlyATTRIBUTE_ReadonlyTEXT_node is a Text node.
+ReadonlyCDATA_node is a CDATASection node.
+ReadonlyENTITY_ReadonlyENTITY_ReadonlyPROCESSING_node is a ProcessingInstruction node.
+ReadonlyCOMMENT_node is a Comment node.
+ReadonlyDOCUMENT_node is a document.
+ReadonlyDOCUMENT_node is a doctype.
+ReadonlyDOCUMENT_node is a DocumentFragment node.
+ReadonlyNOTATION_ReadonlyDOCUMENT_Set when node and other are not in the same tree.
+ReadonlyDOCUMENT_Set when other is preceding node.
+ReadonlyDOCUMENT_Set when other is following node.
+ReadonlyDOCUMENT_Set when other is an ancestor of node.
+ReadonlyDOCUMENT_Set when other is a descendant of node.
+ReadonlyDOCUMENT_ReadonlynextReturns the first following sibling that is an element, and null otherwise.
+ReadonlypreviousReturns the first preceding sibling that is an element, and null otherwise.
+ReadonlychildReadonlychildrenReturns the child elements.
+ReadonlyfirstReturns the first child that is an element, and null otherwise.
+ReadonlylastReturns the last child that is an element, and null otherwise.
+ReadonlyassignedExtended HTMLElement interface for the grid container. +Stores a back-reference to the Angular component for integration purposes.
+Optionaloptions: GetAnimationsOptionsInserts nodes just after node, while replacing strings in nodes with equivalent Text nodes.
+Throws a "HierarchyRequestError" DOMException if the constraints of the node tree are violated.
+Inserts nodes just before node, while replacing strings in nodes with equivalent Text nodes.
+Throws a "HierarchyRequestError" DOMException if the constraints of the node tree are violated.
+Removes node.
+Replaces node with nodes, while replacing strings in nodes with equivalent Text nodes.
+Throws a "HierarchyRequestError" DOMException if the constraints of the node tree are violated.
+Creates a shadow root for element and returns it.
+Optionaloptions: CheckVisibilityOptionsReturns element's first attribute whose qualified name is qualifiedName, and null if there is no such attribute otherwise.
+Returns element's attribute whose namespace is namespace and local name is localName, and null if there is no such attribute otherwise.
+Returns the qualified names of all element's attributes. Can contain duplicates.
+Returns a HTMLCollection of the elements in the object on which the method was invoked (a document or an element) that have all the classes given by classNames. The classNames argument is interpreted as a space-separated list of classes.
+Returns true if element has an attribute whose qualified name is qualifiedName, and false otherwise.
+Returns true if element has an attribute whose namespace is namespace and local name is localName.
+Returns true if element has attributes, and false otherwise.
+Returns true if matching selectors against element's root yields element, and false otherwise.
+Removes element's first attribute whose qualified name is qualifiedName.
+Removes element's attribute whose namespace is namespace and local name is localName.
+Displays element fullscreen and resolves promise when done.
+When supplied, options's navigationUI member indicates whether showing navigation UI while in fullscreen is preferred or not. If set to "show", navigation simplicity is preferred over screen space, and if set to "hide", more screen space is preferred. User agents are always free to honor user preference over the application's. The default value "auto" indicates no application preference.
+Optionaloptions: FullscreenOptionsOptionaloptions: ScrollToOptionsOptionaloptions: ScrollToOptionsOptionalarg: boolean | ScrollIntoViewOptionsOptionaloptions: ScrollToOptionsSets the value of element's first attribute whose qualified name is qualifiedName to value.
+If force is not given, "toggles" qualifiedName, removing it if it is present and adding it if it is not present. If force is true, adds qualifiedName. If force is false, removes qualifiedName.
+Returns true if qualifiedName is now present, and false otherwise.
+Optionalforce: booleanDispatches a synthetic event event to target and returns true if either event's cancelable attribute value is false or its preventDefault() method was not invoked, and false otherwise.
+Optionaloptions: FocusOptionsReturns a copy of node. If deep is true, the copy also includes the node's descendants.
+Optionaldeep: booleanReturns a bitmask indicating the position of other relative to node.
+Returns true if other is an inclusive descendant of node, and false otherwise.
+Returns node's root.
+Optionaloptions: GetRootNodeOptionsReturns whether node has children.
+Returns whether node and otherNode have the same properties.
+Removes empty exclusive Text nodes and concatenates the data of remaining contiguous exclusive Text nodes into the first of their nodes.
+Inserts nodes after the last child of node, while replacing strings in nodes with equivalent Text nodes.
+Throws a "HierarchyRequestError" DOMException if the constraints of the node tree are violated.
+Inserts nodes before the first child of node, while replacing strings in nodes with equivalent Text nodes.
+Throws a "HierarchyRequestError" DOMException if the constraints of the node tree are violated.
+Replace all children of node with nodes, while replacing strings in nodes with equivalent Text nodes.
+Throws a "HierarchyRequestError" DOMException if the constraints of the node tree are violated.
+Optional_Back-reference to the Angular GridStack component
+ReadonlyattributesReadonlyclassAllows for manipulation of element's class content attribute as a set of whitespace-separated tokens through a DOMTokenList object.
+Returns the value of element's class content attribute. Can be set to change it.
+ReadonlyclientReadonlyclientReadonlyclientReadonlyclientReturns the value of element's id content attribute. Can be set to change it.
+ReadonlylocalReturns the local name.
+ReadonlynamespaceReturns the namespace.
+ReadonlyownerReturns the node document. Returns null for documents.
+ReadonlypartReadonlyprefixReturns the namespace prefix.
+ReadonlyscrollReadonlyscrollReadonlyshadowReturns element's shadow root, if any, and if shadow root's mode is "open", and null otherwise.
+Returns the value of element's slot content attribute. Can be set to change it.
+ReadonlytagReturns the HTML-uppercased qualified name.
+ReadonlystyleReadonlyisFires when the user aborts the download.
+Fires when the object loses the input focus.
+Occurs when playback is possible, but would require further buffering.
+Fires when the contents of the object or selection have changed.
+Fires when the user clicks the left mouse button on the object
+Fires when the user clicks the right mouse button in the client area, opening the context menu.
+Fires when the user double-clicks the object.
+Fires on the source object continuously during a drag operation.
+Fires on the source object when the user releases the mouse at the close of a drag operation.
+Fires on the target element when the user drags the object to a valid drop target.
+Fires on the target object when the user moves the mouse out of a valid drop target during a drag operation.
+Fires on the target element continuously while the user drags the object over a valid drop target.
+Fires on the source object when the user starts to drag a text selection or selected object.
+Occurs when the duration attribute is updated.
+Occurs when the media element is reset to its initial state.
+Occurs when the end of playback is reached.
+Fires when an error occurs during object loading.
+Fires when the object receives focus.
+Fires when the user presses a key.
+Fires when the user presses an alphanumeric key.
+Fires when the user releases a key.
+Fires immediately after the browser loads the object.
+Occurs when media data is loaded at the current playback position.
+Occurs when the duration and dimensions of the media have been determined.
+Occurs when Internet Explorer begins looking for media data.
+Fires when the user clicks the object with either mouse button.
+Fires when the user moves the mouse over the object.
+Fires when the user moves the mouse pointer outside the boundaries of the object.
+Fires when the user moves the mouse pointer into the object.
+Fires when the user releases a mouse button while the mouse is over the object.
+Occurs when playback is paused.
+Occurs when the play method is requested.
+Occurs when the audio or video has started playing.
+Occurs to indicate progress while downloading media data.
+Occurs when the playback rate is increased or decreased.
+Fires when the user resets a form.
+Fires when the user repositions the scroll box in the scroll bar on the object.
+Occurs when the seek operation ends.
+Occurs when the current playback position is moved.
+Fires when the current selection changes.
+Occurs when the download has stopped.
+Occurs if the load operation has been intentionally halted.
+Occurs to indicate the current playback position.
+OptionalontouchcancelOptionalontouchendOptionalontouchmoveOptionalontouchstartOccurs when the volume is changed, or playback is muted or unmuted.
+Occurs when playback stops because the next frame of a video resource is not available.
+ReadonlyaccessReadonlyoffsetReadonlyoffsetReadonlyoffsetReadonlyoffsetReadonlyoffsetReadonlydatasetOptionalnonceReadonlybaseReturns node's node document's document base URL.
+ReadonlychildReturns the children.
+ReadonlyfirstReturns the first child.
+ReadonlyisReturns true if node is connected and false otherwise.
+ReadonlylastReturns the last child.
+ReadonlynextReturns the next sibling.
+ReadonlynodeReturns a string appropriate for the type of node.
+ReadonlynodeReturns the type of node.
+ReadonlyparentReturns the parent element.
+ReadonlyparentReturns the parent.
+ReadonlypreviousReturns the previous sibling.
+ReadonlyELEMENT_node is an element.
+ReadonlyATTRIBUTE_ReadonlyTEXT_node is a Text node.
+ReadonlyCDATA_node is a CDATASection node.
+ReadonlyENTITY_ReadonlyENTITY_ReadonlyPROCESSING_node is a ProcessingInstruction node.
+ReadonlyCOMMENT_node is a Comment node.
+ReadonlyDOCUMENT_node is a document.
+ReadonlyDOCUMENT_node is a doctype.
+ReadonlyDOCUMENT_node is a DocumentFragment node.
+ReadonlyNOTATION_ReadonlyDOCUMENT_Set when node and other are not in the same tree.
+ReadonlyDOCUMENT_Set when other is preceding node.
+ReadonlyDOCUMENT_Set when other is following node.
+ReadonlyDOCUMENT_Set when other is an ancestor of node.
+ReadonlyDOCUMENT_Set when other is a descendant of node.
+ReadonlyDOCUMENT_ReadonlynextReturns the first following sibling that is an element, and null otherwise.
+ReadonlypreviousReturns the first preceding sibling that is an element, and null otherwise.
+ReadonlychildReadonlychildrenReturns the child elements.
+ReadonlyfirstReturns the first child that is an element, and null otherwise.
+ReadonlylastReturns the last child that is an element, and null otherwise.
+ReadonlyassignedExtended GridStackNode interface for Angular integration. +Adds component selector for dynamic content creation.
+Extended GridStackOptions interface for Angular integration. +Supports Angular-specific widget definitions and nested grids.
+Extended GridStackWidget interface for Angular integration. +Adds Angular-specific properties for dynamic component creation.
+ngFor: Example using Angular ngFor to loop through items and create DOM items. This track changes made to the array of items, waits for DOM rendering, then update GS
+ + + + +SIMPLEST: angular example using GridStack API directly, so not really using any angular construct per say other than waiting for DOM rendering
+ + + + + `, + // gridstack.min.css and other custom styles should be included in global styles.scss + }) + export class AngularSimpleComponent implements OnInit { + public items: GridStackWidget[] = [ + { x: 0, y: 0, w: 9, h: 6, content: '0' }, + { x: 9, y: 0, w: 3, h: 3, content: '1' }, + { x: 9, y: 3, w: 3, h: 3, content: '2' }, + ]; + private grid!: GridStack; + + constructor() {} + + // simple div above doesn't require Angular to run, so init gridstack here + public ngOnInit() { + this.grid = GridStack.init({ + cellHeight: 70, + }) + .load(this.items); // and load our content directly (will create DOM) + } + + public add() { + this.grid.addWidget({w: 3, content: 'new content'}); + } + public delete() { + this.grid.removeWidget(this.grid.engine.nodes[0].el!); + } + public change() { + this.grid.update(this.grid.engine.nodes[0].el!, {w: 1}); + } + } diff --git a/angular/doc/html/modules.html b/angular/doc/html/modules.html new file mode 100644 index 000000000..1a1141fdf --- /dev/null +++ b/angular/doc/html/modules.html @@ -0,0 +1 @@ +Mapping of selector strings to Angular component types. +Used for dynamic component creation based on widget selectors.
+Callback for drop events with before/after node state
+Type for component input data serialization. +Maps @Input() property names to their values for widget persistence.
+sample showing the different cellHeight options and what happens when you resize the window
+ +The center of the widget shows its dimensions by purely using CSS, no JavaScript involved.
+We now ship an Angular Component + to make it supper easy for that framework
+React original examples are shown above, but upcoming and better TS based /react folder (working to make that official and ship it) should be looked at instead.
+ + + diff --git a/demo/knockout.html b/demo/knockout.html new file mode 100644 index 000000000..108f8bf83 --- /dev/null +++ b/demo/knockout.html @@ -0,0 +1,92 @@ + + + + + + +New V11 GridStackWidget.lazyLoad feature. open console and see widget content (or angular components) created as they become visible.
+shows resize handle on mobile and support native touch events
+ + + + diff --git a/demo/nested.html b/demo/nested.html new file mode 100644 index 000000000..9f3618e39 --- /dev/null +++ b/demo/nested.html @@ -0,0 +1,140 @@ + + + + + + +This example shows v5.x dragging between nested grids (dark yellow) and parent grid (bright yellow.)
+ Use v9.2 sizeToContent:true on first subgrid item parent to grow/shrink as needed, while leaving leaf green items unchanged.
+ Uses v3.1 API to load the entire nested grid from JSON.
+ Nested grids uses v5 column:'auto' to keep items same size during resize.
Create sub-grids (darker background) on the fly, by dragging items completely over others (nest) vs partially (push) using
+ the new v7 API GridStackOptions.subGridDynamic=true
This will use the new delay drag&drop option DDDragOpt.pause to tell the gesture difference
Output
+ + + + diff --git a/demo/nested_constraint.html b/demo/nested_constraint.html new file mode 100644 index 000000000..763d57bc6 --- /dev/null +++ b/demo/nested_constraint.html @@ -0,0 +1,105 @@ + + + + + + +This example shows sub-grids only accepting pink items, while parent accept all.
+ Add Widget + Add Widget Grid1 + Add Widget Grid2 + entire save/re-create: + Save + Destroy + Create + partial save/load: + Save list + Save no content + Clear + Load ++ As with any virtual DOM based framework, you need to check if React has rendered the DOM (or any updates to it) + before you initialize GridStack or call its methods. This example shows how to make rendered + components widgets: +
+Using new v10 GridStackOptions.columnOpts: { columnWidth: x }
Using new v10 GridStackOptions.columnOpts: { breakpoints: [] }
show loading a fixed (layout:'none') but still responsive design (150px columns) with items w:2-4
+showing how it will not change the layout unless it doesn't fit. loading into small view remembers the full layout (column:6)
+ +New 9.x feature that size the items to fit their content height as to not have scroll bars
+
case C: `sizeToContent:false` to turn off.
+
case E: has soft maxsize `sizeToContent:3`, shrinking to smaller content as needed
+
Defaulting to different initial size (see code) to show grow/shrink behavior
from DOM test:
+we start with a static grid (no drag&drop initialized) with button to make it editable.
+ + + + +example where the grid parent has a translate(50px, 100px) and a scale(, )
+Two grids, one floating one not, showing drag&drop from sidebar and between grids.
+
New v10.2: use 'Esc' to cancel any move/resize. Use 'r' to rotate as you drag.
special care is needed to prevent top grid from growing and causing shifts while you are dragging (which is a know issue).
+ You can either set a fix row, or have enough padding on a parent div to allow for an extra row to be created as needed), or....
+ As with any virtual DOM based framework, you need to check if Vue has
+ rendered the DOM (or any updates to it) before you
+ initialize GridStack or call its methods. As a basic example, check this
+ component's mounted hook.
+
+ If your app requires more complex render logic than the inline template + in `addWidget`, consider + makeWidget + to let Vue deal with DOM rendering. +
+ {{ info }} + +
+ As with any virtual DOM based framework, you need to check if Vue has
+ rendered the DOM (or any updates to it) before you
+ initialize GridStack or call its methods. As a basic example, check this
+ component's mounted hook.
+
+ If your app requires more complex render logic than the inline template + in `addWidget`, consider + makeWidget + to let Vue deal with DOM rendering. +
+ {{ info }} + +
+ Use Vue3 render functions with GridStack.renderCB
+ GridStack handles widget creation and Vue handles rendering the content using the modern (since V11) GridStack.renderCB.
+
+ Helpful Resources: +
+ + {{ info }} + +
+ Use Vue3 render functions to dynamically render only the grid item content.
+ GridStack is handles when items are added/removed, rendering grid item element, and Vue handles rendering only the item content.
+
+ Helpful Resources: +
+ ++ Notes: +
+ Use Vue3 render functions to dynamically render the entire Gridstack item (wrapper and contents)
+ GridStack is handles when items are added/removed, and Vue handles rendering of the entire item in GridStack.addRemoveCB.
+
+ Helpful Resources: +
+ ++ Notes: +
+ As with any virtual DOM based framework, you need to check if Vue has
+ rendered the DOM (or any updates to it) before you
+ initialize GridStack or call its methods. As a basic example, check this
+ component's mounted hook.
+
+ If your app requires more complex render logic than the inline template + in `addWidget`, consider + makeWidget + to let Vue deal with DOM rendering. +
+ + +AbstractAbstract base class for all drag & drop implementations. +Provides common functionality for event handling, enable/disable state, +and lifecycle management used by draggable, droppable, and resizable implementations.
+Returns the current disabled state. +Note: Use enable()/disable() methods to change state as other operations need to happen.
+Destroy this drag & drop implementation and clean up resources. +Removes all event handlers and clears internal state.
+Disable this drag & drop implementation. +Subclasses should override to perform additional cleanup.
+Enable this drag & drop implementation. +Subclasses should override to perform additional setup.
+Unregister an event callback for the specified event.
+Event name to stop listening for
+Register an event callback for the specified event.
+Event name to listen for
+Function to call when event occurs
+Trigger a registered event callback if one exists and the implementation is enabled.
+Name of the event to trigger
+DOM event object to pass to the callback
+Result from the callback function, if any
+Interface for HTML elements extended with drag & drop options. +Used to associate DD configuration with DOM elements.
+Returns the current disabled state. +Note: Use enable()/disable() methods to change state as other operations need to happen.
+Destroy this drag & drop implementation and clean up resources. +Removes all event handlers and clears internal state.
+Disable this drag & drop implementation. +Subclasses should override to perform additional cleanup.
+Enable this drag & drop implementation. +Subclasses should override to perform additional setup.
+Unregister an event callback for the specified event.
+Event name to stop listening for
+Register an event callback for the specified event.
+Event name to listen for
+Function to call when event occurs
+Trigger a registered event callback if one exists and the implementation is enabled.
+Name of the event to trigger
+DOM event object to pass to the callback
+Result from the callback function, if any
+Method to update the options and return the DD implementation
+Interface for HTML elements extended with drag & drop options. +Used to associate DD configuration with DOM elements.
+Returns the current disabled state. +Note: Use enable()/disable() methods to change state as other operations need to happen.
+Destroy this drag & drop implementation and clean up resources. +Removes all event handlers and clears internal state.
+Disable this drag & drop implementation. +Subclasses should override to perform additional cleanup.
+item is being dropped on us - called by the drag mouseup handler - this calls the client drop event
+Enable this drag & drop implementation. +Subclasses should override to perform additional setup.
+Unregister an event callback for the specified event.
+Event name to stop listening for
+Register an event callback for the specified event.
+Event name to listen for
+Function to call when event occurs
+Trigger a registered event callback if one exists and the implementation is enabled.
+Name of the event to trigger
+DOM event object to pass to the callback
+Result from the callback function, if any
+Method to update the options and return the DD implementation
+StaticinitHTML Native Mouse and Touch Events Drag and Drop functionality.
+This class provides the main drag & drop implementation for GridStack, +handling resizing, dragging, and dropping of grid items using native HTML5 events. +It manages the interaction between different DD components and the grid system.
+Enable/disable/configure dragging for grid elements.
+Grid item element(s) to configure
+Drag options or command ('enable', 'disable', 'destroy', 'option', or config object)
+Optionalkey: DDKeyOption key when using 'option' command
+Optionalvalue: DDValueOption value when using 'option' command
+this instance for chaining
+Optionalkey: DDKeyOptionalvalue: DDValueEnable/disable/configure resizing for grid elements.
+Grid item element(s) to configure
+Resize options or command ('enable', 'disable', 'destroy', 'option', or config object)
+Optionalkey: DDKeyOption key when using 'option' command
+Optionalvalue: DDValueOption value when using 'option' command
+this instance for chaining
+Global state manager for all Drag & Drop instances.
+This class maintains shared state across all drag & drop operations, +ensuring proper coordination between multiple grids and drag/drop elements. +All properties are static to provide global access throughout the DD system.
+StaticdragReference to the element currently being dragged. +Used to track the active drag operation across the system.
+StaticdropReference to the drop target element currently under the cursor. +Used to handle drop operations and hover effects.
+StaticmouseFlag indicating if a mouse down event was already handled. +Prevents multiple handlers from processing the same mouse event.
+StaticoverReference to the element currently being resized. +Helps ignore nested grid resize handles during resize operations.
+StaticpauseControls drag operation pausing behavior. +If set to true or a number (milliseconds), dragging placement and collision +detection will only happen after the user pauses movement. +This improves performance during rapid mouse movements.
+Interface for HTML elements extended with drag & drop options. +Used to associate DD configuration with DOM elements.
+Returns the current disabled state. +Note: Use enable()/disable() methods to change state as other operations need to happen.
+Destroy this drag & drop implementation and clean up resources. +Removes all event handlers and clears internal state.
+Disable this drag & drop implementation. +Subclasses should override to perform additional cleanup.
+Enable this drag & drop implementation. +Subclasses should override to perform additional setup.
+Unregister an event callback for the specified event.
+Event name to stop listening for
+Register an event callback for the specified event.
+Event name to listen for
+Function to call when event occurs
+Trigger a registered event callback if one exists and the implementation is enabled.
+Name of the event to trigger
+DOM event object to pass to the callback
+Result from the callback function, if any
+Method to update the options and return the DD implementation
+call this when resize handle needs to be removed and cleaned up
+Main gridstack class - you will need to call GridStack.init() first to initialize your grid.
+Note: your grid elements MUST have the following classes for the CSS layout to work:
Construct a grid item from the given element and options
+the HTML element tied to this grid after it's been initialized
+grid options - public for classes to access, but use methods to modify!
+Protected_add or remove the grid element size event handler
+Protected_return our expected width (or parent) , and optionally of window for dynamic column check
+Staticaddcall to create a grid with the given options, including loading any children from JSON structure. This will call GridStack.init(), then +grid.load() on any passed children (recursively). Great alternative to calling init() if you want entire grid to come from +JSON serialized data, including options.
+HTML element parent to the grid
+grids options used to initialize the grid, and list of children
+add a new widget and returns it.
+Widget will be always placed even if result height is more than actual grid height.
+You need to use willItFit() before calling addWidget for additional check.
+See also makeWidget(el) for DOM element.
GridStackWidget definition. used MakeWidget(el) if you have dom element instead.
+use before calling a bunch of addWidget() to prevent un-necessary relayouts in between (more efficient)
+and get a single event callback. You will see no changes until batchUpdate(false) is called.
Update current cell height - see GridStackOptions.cellHeight for format by updating eh Browser CSS variable.
Optionalval: numberOrStringthe cell height. Options:
+undefined: cells content will be made square (match width minus margin)0: the CSS will be generated by the application insteadthe grid instance for chaining
+Gets the current cell width in pixels. This is calculated based on the grid container width divided by the number of columns.
+the cell width in pixels
+Protectedcheckchecks for dynamic column count for our current size, returning true if changed
+Set the number of columns in the grid. Will update existing widgets to conform to new number of columns, +as well as cache the original layout so you can revert back to previous positions without loss.
+Requires gridstack-extra.css or gridstack-extra.min.css for [2-11] columns,
+else you will need to generate correct CSS.
+See: https://github.com/gridstack/gridstack.js#change-grid-columns
Integer > 0 (default 12)
+specify the type of re-layout that will happen. Options:
+column=1 as we always want to vertically stack.the grid instance for chaining
+Re-layout grid items to reclaim any empty space. This is useful after removing widgets +or when you want to optimize the layout.
+layout type. Options:
+re-sort items first based on x,y position. Set to false to do your own sorting ahead (default: true)
+the grid instance for chaining
+Create the default grid item divs and content (possibly lazy loaded) by using GridStack.renderCB().
+GridStackNode definition containing widget configuration
+the created HTML element with proper grid item structure
+Destroys a grid instance. DO NOT CALL any methods or access any vars after this as it will free up members.
+if false grid and items HTML elements will not be removed from the DOM (Optional. Default true).
Temporarily disables widgets moving/resizing.
+If you want a more permanent way (which freezes up resources) use setStatic(true) instead.
Note: This is a no-op for static grids.
+This is a shortcut for:
+grid.enableMove(false);
grid.enableResize(false);
+
+
+if true (default), sub-grids also get updated
+the grid instance for chaining
+Re-enables widgets moving/resizing - see disable(). +Note: This is a no-op for static grids.
+This is a shortcut for:
+grid.enableMove(true);
grid.enableResize(true);
+
+
+if true (default), sub-grids also get updated
+the grid instance for chaining
+Enables/disables widget moving for all widgets. No-op for static grids. +Note: locally defined items (with noMove property) still override this setting.
+if true widgets will be movable, if false moving is disabled
+if true (default), sub-grids also get updated
+the grid instance for chaining
+Enables/disables widget resizing for all widgets. No-op for static grids. +Note: locally defined items (with noResize property) still override this setting.
+if true widgets will be resizable, if false resizing is disabled
+if true (default), sub-grids also get updated
+the grid instance for chaining
+Get the position of the cell under a pixel on screen.
+the position of the pixel to resolve in +absolute coordinates, as an object with top and left properties
+if true, value will be based on document position vs parent position (Optional. Default false).
+Useful when grid is within position: relative element
Returns an object with properties x and y i.e. the column and row in the grid.
Gets the current cell height in pixels. This takes into account the unit type and converts to pixels if necessary.
+if true, forces conversion to pixels even when cellHeight is specified in other units
+the cell height in pixels
+StaticgetGet the global drag & drop implementation instance. +This provides access to the underlying drag & drop functionality.
+the DDGridStack instance used for drag & drop operations
+Returns an array of grid HTML elements (no placeholder) - used to iterate through our children in DOM order. +This method excludes placeholder elements and returns only actual grid items.
+array of GridItemHTMLElement instances representing all grid items
+Returns the current margin value as a number (undefined if the 4 sides don't match). +This only returns a number if all sides have the same margin value.
+the margin value in pixels, or undefined if sides have different values
+Staticinitinitializing the HTML element, or selector string, into a grid will return the grid. Calling it again will +simply return the existing instance (ignore any passed options). There is also an initAll() version that support +multiple grids initialization at once. Or you can use addGrid() to create the entire grid from JSON.
+grid options (optional)
+element or CSS selector (first one used) to convert to a grid (default to '.grid-stack' class selector)
+StaticinitWill initialize a list of elements (given a selector) and return an array of grids.
+grid options (optional)
+elements selector to convert to grids (default to '.grid-stack' class selector)
+Checks if the specified rectangular area is empty (no widgets occupy any part of it).
+the x coordinate (column) of the area to check
+the y coordinate (row) of the area to check
+the width in columns of the area to check
+the height in rows of the area to check
+true if the area is completely empty, false if any widget overlaps
+Returns true if change callbacks should be ignored due to column change, sizeToContent, loading, etc. +This is useful for callers who want to implement dirty flag functionality.
+true if change callbacks are currently being ignored
+Load widgets from a list. This will call update() on each (matching by id) or add/remove widgets that are not there.
+Used to restore a grid layout for a saved layout list (see save()).
list of widgets definition to update/create
+boolean (default true) or callback method can be passed to control if and how missing widgets can be added/removed, giving +the user control of insertion.
+the grid instance for chaining
+// Basic usage with saved layout
const savedLayout = grid.save(); // Save current layout
// ... later restore it
grid.load(savedLayout);
// Load with custom add/remove callback
grid.load(layout, (items, grid, add) => {
if (add) {
// Custom logic for adding new widgets
items.forEach(item => {
const el = document.createElement('div');
el.innerHTML = item.content || '';
grid.addWidget(el, item);
});
} else {
// Custom logic for removing widgets
items.forEach(item => grid.removeWidget(item.el));
}
});
// Load without adding/removing missing widgets
grid.load(layout, false);
+
+
+http://gridstackjs.com/demo/serialization.html for complete example
+Convert an existing gridItem element into a sub-grid with the given (optional) options, else inherit them +from the parent's subGrid options.
+gridItem element to convert
+Optionalops: GridStackOptions(optional) sub-grid options, else default to node, then parent settings, else defaults
+OptionalnodeToAdd: GridStackNode(optional) node to add to the newly created sub grid (used when dragging over existing regular item)
+if true (default) the html inside .grid-stack-content will be saved to child widget
+newly created grid
+If you add elements to your grid by hand (or have some framework creating DOM), you have to tell gridstack afterwards to make them widgets.
+If you want gridstack to add the elements for you, use addWidget() instead.
+Makes the given element a widget and returns it.
widget or single selector to convert.
+Optionaloptions: GridStackWidgetwidget definition to use instead of reading attributes or using default sizing values
+the converted GridItemHTMLElement
+const grid = GridStack.init();
// Create HTML content manually, possibly looking like:
// <div id="item-1" gs-x="0" gs-y="0" gs-w="3" gs-h="2"></div>
grid.el.innerHTML = '<div id="item-1" gs-w="3"></div><div id="item-2"></div>';
// Convert existing elements to widgets
grid.makeWidget('#item-1'); // Uses gs-* attributes from DOM
grid.makeWidget('#item-2', {w: 2, h: 1, content: 'Hello World'});
// Or pass DOM element directly
const element = document.getElementById('item-3');
grid.makeWidget(element, {x: 0, y: 1, w: 4, h: 2});
+
+
+Updates the margins which will set all 4 sides at once - see GridStackOptions.margin for format options.
+Supports CSS string format of 1, 2, or 4 values or a single number.
margin value - can be:
+10 (applies to all sides)'10px 20px' (top/bottom, left/right)'10px 20px 5px 15px' (top, right, bottom, left)the grid instance for chaining
+Enables/Disables dragging by the user for specific grid elements. +For all items and future items, use enableMove() instead. No-op for static grids.
+Note: If you want to prevent an item from moving due to being pushed around by another +during collision, use the 'locked' property instead.
+widget element(s) or selector to modify
+if true widget will be draggable, assuming the parent grid isn't noMove or static
+the grid instance for chaining
+unsubscribe from the 'on' event GridStackEvent
+of the event (see possible values) or list of names space separated
+Remove all event handlers from the grid. This is useful for cleanup when destroying a grid.
+the grid instance for chaining
+Register event handler for grid events. You can call this on a single event name, or space separated list.
+Supported events:
+added: Called when widgets are being added to a gridchange: Occurs when widgets change their position/size due to constraints or direct changesdisable: Called when grid becomes disableddragstart: Called when grid item starts being draggeddrag: Called while grid item is being dragged (for each new row/column value)dragstop: Called after user is done moving the item, with updated DOM attributesdropped: Called when an item has been dropped and accepted over a gridenable: Called when grid becomes enabledremoved: Called when items are being removed from the gridresizestart: Called before user starts resizing an itemresize: Called while grid item is being resized (for each new row/column value)resizestop: Called after user is done resizing the item, with updated DOM attributesevent name(s) to listen for (space separated for multiple)
+function to call when event occurs
+the grid instance for chaining
+Register event handler for grid events. You can call this on a single event name, or space separated list.
+Supported events:
+added: Called when widgets are being added to a gridchange: Occurs when widgets change their position/size due to constraints or direct changesdisable: Called when grid becomes disableddragstart: Called when grid item starts being draggeddrag: Called while grid item is being dragged (for each new row/column value)dragstop: Called after user is done moving the item, with updated DOM attributesdropped: Called when an item has been dropped and accepted over a gridenable: Called when grid becomes enabledremoved: Called when items are being removed from the gridresizestart: Called before user starts resizing an itemresize: Called while grid item is being resized (for each new row/column value)resizestop: Called after user is done resizing the item, with updated DOM attributesevent name(s) to listen for (space separated for multiple)
+function to call when event occurs
+the grid instance for chaining
+Register event handler for grid events. You can call this on a single event name, or space separated list.
+Supported events:
+added: Called when widgets are being added to a gridchange: Occurs when widgets change their position/size due to constraints or direct changesdisable: Called when grid becomes disableddragstart: Called when grid item starts being draggeddrag: Called while grid item is being dragged (for each new row/column value)dragstop: Called after user is done moving the item, with updated DOM attributesdropped: Called when an item has been dropped and accepted over a gridenable: Called when grid becomes enabledremoved: Called when items are being removed from the gridresizestart: Called before user starts resizing an itemresize: Called while grid item is being resized (for each new row/column value)resizestop: Called after user is done resizing the item, with updated DOM attributesevent name(s) to listen for (space separated for multiple)
+function to call when event occurs
+the grid instance for chaining
+Register event handler for grid events. You can call this on a single event name, or space separated list.
+Supported events:
+added: Called when widgets are being added to a gridchange: Occurs when widgets change their position/size due to constraints or direct changesdisable: Called when grid becomes disableddragstart: Called when grid item starts being draggeddrag: Called while grid item is being dragged (for each new row/column value)dragstop: Called after user is done moving the item, with updated DOM attributesdropped: Called when an item has been dropped and accepted over a gridenable: Called when grid becomes enabledremoved: Called when items are being removed from the gridresizestart: Called before user starts resizing an itemresize: Called while grid item is being resized (for each new row/column value)resizestop: Called after user is done resizing the item, with updated DOM attributesevent name(s) to listen for (space separated for multiple)
+function to call when event occurs
+the grid instance for chaining
+Register event handler for grid events. You can call this on a single event name, or space separated list.
+Supported events:
+added: Called when widgets are being added to a gridchange: Occurs when widgets change their position/size due to constraints or direct changesdisable: Called when grid becomes disableddragstart: Called when grid item starts being draggeddrag: Called while grid item is being dragged (for each new row/column value)dragstop: Called after user is done moving the item, with updated DOM attributesdropped: Called when an item has been dropped and accepted over a gridenable: Called when grid becomes enabledremoved: Called when items are being removed from the gridresizestart: Called before user starts resizing an itemresize: Called while grid item is being resized (for each new row/column value)resizestop: Called after user is done resizing the item, with updated DOM attributesevent name(s) to listen for (space separated for multiple)
+function to call when event occurs
+the grid instance for chaining
+called when we are being resized - check if the one Column Mode needs to be turned on/off
+and remember the prev columns we used, or get our count from parent, as well as check for cellHeight==='auto' (square)
+or sizeToContent gridItem options.
prepares the element for drag&drop - this is normally called by makeWidget() unless are are delay loading
+GridItemHTMLElement of the widget
+Optionalforce: boolean = falseStaticregistercall this method to register your engine instead of the default one.
+See instead GridStackOptions.engineClass if you only need to
+replace just one instance.
Removes all widgets from the grid.
+if false DOM elements won't be removed from the tree (Default? true).
if false (quiet mode) element will not be added to removed list and no 'removed' callbacks will be called (Default? true).
called when an item was converted into a nested grid to accommodate a dragged over item, but then item leaves - return back +to the original grid-item. Also called to remove empty sub-grids when last item is dragged out (since re-creating is simple)
+OptionalnodeThatRemoved: GridStackNodeRemoves widget from the grid.
+if false DOM element won't be removed from the tree (Default? true).
if false (quiet mode) element will not be added to removed list and no 'removed' callbacks will be called (Default? true).
Enables/Disables user resizing for specific grid elements. +For all items and future items, use enableResize() instead. No-op for static grids.
+widget element(s) or selector to modify
+if true widget will be resizable, assuming the parent grid isn't noResize or static
+the grid instance for chaining
+Updates widget height to match the content height to avoid vertical scrollbars or dead space. +This automatically adjusts the widget height based on its content size.
+Note: This assumes only 1 child under resizeToContentParent='.grid-stack-item-content' +(sized to gridItem minus padding) that represents the entire content size.
+the grid item element to resize
+Rotate widgets by swapping their width and height. This is typically called when the user presses 'r' during dragging. +The rotation swaps the w/h dimensions and adjusts min/max constraints accordingly.
+widget element(s) or selector to rotate
+Optionalrelative: Positionoptional pixel coordinate relative to upper/left corner to rotate around (keeps that cell under cursor)
+the grid instance for chaining
+saves the current layout returning a list of widgets for serialization which might include any nested grids.
+if true (default) the latest html inside .grid-stack-content will be saved to GridStackWidget.content field, else it will +be removed.
+if true (default false), save the grid options itself, so you can call the new GridStack.addGrid() +to recreate everything from scratch. GridStackOptions.children would then contain the widget list instead.
+callback for each node -> widget, so application can insert additional data to be saved into the widget data structure.
+Optionalcolumn: numberif provided, the grid will be saved for the given column size (IFF we have matching internal saved layout, or current layout). +Otherwise it will use the largest possible layout (say 12 even if rendering at 1 column) so we can restore to all layouts. +NOTE: if you want to save to currently display layout, pass this.getColumn() as column. +NOTE2: nested grids will ALWAYS save to the container size to be in sync with parent.
+list of widgets or full grid option, including .children list of widgets
+Toggle the grid animation state. Toggles the grid-stack-animate class.
if true the grid will animate.
+Optionaldelay: booleanif true setting will be set on next event loop.
+Toggle the grid static state, which permanently removes/add Drag&Drop support, unlike disable()/enable() that just turns it off/on. +Also toggle the grid-stack-static class.
+if true the grid become static.
+true (default) if css class gets updated
+true (default) if sub-grids also get updated
+Staticsetupcall to setup dragging in from the outside (say toolbar), by specifying the class selection and options. +Called during GridStack.init() as options, but can also be called directly (last param are used) in case the toolbar +is dynamically create and needs to be set later.
+OptionaldragIn: string | HTMLElement[]string selector (ex: '.sidebar-item') or list of dom elements
+OptionaldragInOptions: DDDragOptoptions - see DDDragOpt. (default: {handle: '.grid-stack-item-content', appendTo: 'body'}
+Optionalwidgets: GridStackWidget[]GridStackWidget def to assign to each element which defines what to create on drop
+optional root which defaults to document (for shadow dom pass the parent HTMLDocument)
+Protectedtriggercall given event callback on our main top-most grid (if we're nested)
+Updates widget position/size and other info. This is used to change widget properties after creation. +Can update position, size, content, and other widget properties.
+Note: If you need to call this on all nodes, use load() instead which will update what changed. +Setting the same x,y for multiple items will be indeterministic and likely unwanted.
+widget element(s) or selector to modify
+new widget options (x,y,w,h, etc.). Only those set will be updated.
+the grid instance for chaining
+Updates the passed in options on the grid (similar to update(widget) for for the grid options).
+Returns true if the height of the grid will be less than the vertical +constraint. Always returns true if grid doesn't have height constraint.
+contains x,y,w,h,auto-position options
+Static Optionaladdcallback method use when new items|grids needs to be created or deleted, instead of the default +item:
time to wait for animation (if enabled) to be done so content sizing can happen
+the HTML element tied to this grid after it's been initialized
+engine used to implement non DOM grid functionality
+StaticEnginescoping so users can call new GridStack.Engine(12) for example
+Protected Staticenginegrid options - public for classes to access, but use methods to modify!
+Optionalparentpoint to a parent grid item if we're nested (inside a grid-item in between 2 Grids)
+Static Optionalrendercallback to create the content of widgets so the app can control how to store and restore it +By default this lib will do 'el.textContent = w.content' forcing text only support for avoiding potential XSS issues.
+ProtectedresizeStatic Optionalresizecallback to use for resizeToContent instead of the built in one
+Staticresizeparent class for sizing content. defaults to '.grid-stack-item-content'
+ProtectedresponseStatic Optionalsavecallback during saving to application can inject extra data for each widget, on top of the grid layout properties
+Static Optionalupdatecalled after a widget has been updated (eg: load() into an existing list of children) so application can do extra work
+StaticUtilsscoping so users can call GridStack.Utils.sort() for example
+Defines the GridStack engine that handles all grid layout calculations and node positioning. +This is the core engine that performs grid manipulation without any DOM operations.
+The engine manages:
+NOTE: Values should not be modified directly - use the main GridStack API instead +to ensure proper DOM updates and event triggers.
+Enable/disable floating widgets (default: false).
+When floating is enabled, widgets can move up to fill empty spaces.
+See example
true to enable floating, false to disable
+Protected_Add the given node to the grid, handling collision detection and re-packing. +This is the main method for adding new widgets to the engine.
+the node to add to the grid
+if true, adds node to addedNodes list for event triggering
+Optionalafter: GridStackNodeoptional node to place this node after (for ordering)
+the added node (or existing node if duplicate)
+Enable/disable batch mode for multiple operations to optimize performance. +When enabled, layout updates are deferred until batch mode is disabled.
+true to enable batch mode, false to disable and apply changes
+if true (default), pack/compact nodes when disabling batch mode
+the engine instance for chaining
+call to cache the given layout internally to the given location so we can restore back when column changes size
+list of nodes
+corresponding column index to save it under
+if true, will force other caches to be removed (default false)
+call to cache the given node layout internally to the given location so we can restore back when column changes size
+corresponding column index to save it under
+true if x,y or w,h are different after clamping to min/max
+called to remove all internal values but the _id
+Return the first node that intercepts/collides with the given node or area. +Used for collision detection during drag and drop operations.
+the node to skip in collision detection (usually the node being moved)
+the area to check for collisions (defaults to skip node's area)
+Optionalskip2: GridStackNodeoptional second node to skip in collision detection
+the first colliding node, or undefined if no collision
+Return all nodes that intercept/collide with the given node or area. +Similar to collide() but returns all colliding nodes instead of just the first.
+the node to skip in collision detection
+the area to check for collisions (defaults to skip node's area)
+Optionalskip2: GridStackNodeoptional second node to skip in collision detection
+array of all colliding nodes
+Re-layout grid items to reclaim any empty space. +This optimizes the grid layout by moving items to fill gaps.
+layout algorithm to use:
+if true (default), sort nodes by position before compacting
+the engine instance for chaining
+Protecteddirectiondoes a pixel coverage collision based on where we started, returning the node that has the most coverage that is >50% mid line
+ProtectedfindFind the first available empty spot for the given node dimensions. +Updates the node's x,y attributes with the found position.
+the node to find a position for (w,h must be set)
+optional list of nodes to check against (defaults to engine nodes)
+optional column count (defaults to engine column count)
+Optionalafter: GridStackNodeoptional node to start search after (maintains order)
+true if an empty position was found and node was updated
+Returns a list of nodes that have been modified from their original values. +This is used to track which nodes need DOM updates.
+Optionalverify: booleanif true, performs additional verification by comparing current vs original positions
+array of nodes that have been modified
+Check if the specified rectangular area is empty (no nodes occupy any part of it).
+the x coordinate (column) of the area to check
+the y coordinate (row) of the area to check
+the width in columns of the area to check
+the height in rows of the area to check
+true if the area is completely empty, false if any node overlaps
+return true if the passed in node was actually moved (checks for no-op and locked)
+Check if a node can be moved to a new position, considering layout constraints. +This is a safer version of moveNode() that validates the move first.
+For complex cases (like maxRow constraints), it simulates the move in a clone first, +then applies the changes only if they meet all specifications.
+the node to move
+move options including target position
+true if the node was successfully moved
+Part 2 of preparing a node to fit inside the grid - validates and fixes coordinates and dimensions. +This ensures the node fits within grid boundaries and respects min/max constraints.
+the node to validate and fix
+Optionalresizing: booleanif true, resize the node to fit; if false, move the node to fit
+the engine instance for chaining
+Prepare and validate a node's coordinates and values for the current grid. +This ensures the node has valid position, size, and properties before being added to the grid.
+the node to prepare and validate
+Optionalresizing: booleanif true, resize the node down if it's out of bounds; if false, move it to fit
+the prepared node with valid coordinates
+Remove all nodes from the grid.
+if true (default), marks all nodes for DOM removal
+if true (default), triggers removal events
+the engine instance for chaining
+Remove the given node from the grid.
+the node to remove
+if true (default), marks node for DOM removal
+if true, adds node to removedNodes list for event triggering
+the engine instance for chaining
+saves a copy of the largest column layout (eg 12 even when rendering 1 column) so we don't loose orig layout, unless explicity column +count to use is given. returning a list of widgets for serialization
+if true (default), the element will be saved to GridStackWidget.el field, else it will be removed.
+OptionalsaveCB: SaveFcncallback for each node -> widget, so application can insert additional data to be saved into the widget data structure.
+Optionalcolumn: numberif provided, the grid will be saved for the given column count (IFF we have matching internal saved layout, or current layout). +Note: nested grids will ALWAYS save the container w to match overall layouts (parent + child) to be consistent.
+Sort the nodes array from first to last, or reverse. +This is called during collision/placement operations to enforce a specific order.
+sort direction: 1 for ascending (first to last), -1 for descending (last to first)
+the engine instance for chaining
+Attempt to swap the positions of two nodes if they meet swapping criteria. +Nodes can swap if they are the same size or in the same column/row, not locked, and touching.
+first node to swap
+second node to swap
+true if swap was successful, false if not possible, undefined if not applicable
+return true if can fit in grid height constrain only (always true if no maxRow)
+Collection of utility methods used throughout GridStack. +These are general-purpose helper functions for DOM manipulation, +positioning calculations, object operations, and more.
+StaticaddStaticappendStaticareaCalculate the total area of a grid position.
+position with width and height
+the total area (width * height)
+StaticareaCalculate the overlapping area between two grid positions.
+first position
+second position
+the area of overlap (0 if no overlap)
+Staticcantrue if the item can be rotated (checking for prop, not space available)
+StaticcloneStaticcloneStaticclonedeep clone the given HTML node, removing teh unique id field
+StaticcopyCopy position and size properties from one widget to another. +Copies x, y, w, h and optionally min/max constraints.
+target widget to copy to
+source widget to copy from
+if true, also copy min/max width/height constraints
+the target widget (a)
+StaticcreateCreate a div element with the specified CSS classes.
+array of CSS class names to add
+Optionalparent: HTMLElementoptional parent element to append the div to
+the created div element
+StaticdefaultsCopy unset fields from source objects to target object (shallow merge with defaults). +Similar to Object.assign but only sets undefined/null fields.
+the object to copy defaults into
+one or more source objects to copy defaults from
+the modified target object
+StaticfindFind a grid node by its ID.
+array of nodes to search
+the ID to search for
+the node with matching ID, or undefined if not found
+StaticgetConvert a potential selector into a single HTML element. +Similar to getElements() but returns only the first match.
+selector string or HTMLElement
+optional root element to search within (defaults to document)
+the first HTML element matching the selector, or null if not found
+StaticgetConvert a potential selector into an actual list of HTML elements. +Supports CSS selectors, element references, and special ID handling.
+selector string, HTMLElement, or array of elements
+optional root element to search within (defaults to document, useful for shadow DOM)
+array of HTML elements matching the selector
+Staticgetdefines an element that is used to get the offset and scale from grid transforms +returns the scale and offsets from said element
+StaticinitStaticisCheck if two grid positions overlap/intersect.
+first position with x, y, w, h properties
+second position with x, y, w, h properties
+true if the positions overlap
+StaticisCheck if two grid positions are touching (edges or corners).
+first position
+second position
+true if the positions are touching
+StaticlazyCheck if a widget should be lazy loaded based on node or grid settings.
+the grid node to check
+true if the item should be lazy loaded
+StaticparseParse a height value with units into numeric value and unit string. +Supports px, em, rem, vh, vw, %, cm, mm units.
+height value as number or string with units
+object with h (height) and unit properties
+Staticremoveremoves field from the first object if same as the second objects (like diffing) and internal '_' for saving
+Staticremoveremoves internal fields '_' and default values for saving
+StaticremoveStaticsameCompare two objects for equality (shallow comparison). +Checks if objects have the same fields and values at one level deep.
+first object to compare
+second object to compare
+true if objects have the same values
+Staticsametrue if a and b has same size & position
+StaticsanitizeStaticshouldCheck if a widget should resize to fit its content.
+the grid node to check (can be undefined)
+if true, only returns true for explicit sizeToContent:true (not numbers)
+true if the widget should resize to content
+Staticsimulatecopies the MouseEvent (or convert Touch) properties and sends it as another event to the given target
+Optionaltarget: EventTargetStaticsortSort an array of grid nodes by position (y first, then x).
+array of nodes to sort
+sort direction: 1 for ascending (top-left first), -1 for descending
+the sorted array (modifies original)
+Staticswapswap the given object 2 field values
+Staticthrottledelay calling the given function for given delay, preventing new calls from happening while waiting
+StatictoStatictoDefines a responsive breakpoint for automatic column count changes. +Used with the responsive.breakpoints option.
+Drag&Drop dragging options
+Optionalappenddefault to 'body'
+Optionalcancelprevents dragging from starting on specified elements, listed as comma separated selectors (eg: '.no-drag'). default built in is 'input,textarea,button,select,option'
+OptionaldragOptionalhandleclass selector of items that can be dragged. default to '.grid-stack-item-content'
+Optionalhelperhelper function when dropping: 'clone' or your own method
+Optionalpauseif set (true | msec), dragging placement (collision) will only happen after a pause by the user. Note: this is Global
+Optionalscrolldefault to true
Optionalstartcallbacks
+OptionalstopExtended HTMLElement interface for grid items. +All grid item DOM elements implement this interface to provide access to their grid data.
+Drag&Drop remove options
+Drag&Drop resize options
+Optionalautodo resize handle hide by default until mouse over. default: true on desktop, false on mobile
+OptionalelementCustom element or query inside the widget node that is used instead of the +generated resize handle.
+Optionalhandlessides where you can resize from (ex: 'e, se, s, sw, w') - default 'se' (south-east) +Note: it is not recommended to resize from the top sides as weird side effect may occur.
+OptionalmaxOptionalmaxOptionalmaxOptionalmaxOptionalminOptionalminOptionalresizeOptionalstartOptionalstopDrag&Drop resize options
+Optionalautodo resize handle hide by default until mouse over. default: true on desktop, false on mobile
+OptionalelementCustom element or query inside the widget node that is used instead of the +generated resize handle.
+Optionalhandlessides where you can resize from (ex: 'e, se, s, sw, w') - default 'se' (south-east) +Note: it is not recommended to resize from the top sides as weird side effect may occur.
+Extended HTMLElement interface for grid items. +All grid item DOM elements implement this interface to provide access to their grid data.
+options used during creation - similar to GridStackOptions
+options used during GridStackEngine.moveNode()
+OptionalcellOptionalcellvars to calculate other cells coordinates
+Optionalcollidebest node (most coverage) we collied with
+Optionalforcefor collision check even if we don't move
+Optionalhwidget dimension height (default?: 1)
+OptionalmarginOptionalmarginOptionalmarginOptionalmarginOptionalnestedtrue if we are calling this recursively to prevent simple swap or coverage collision - default false
+Optionalpackdo we pack (default true)
+Optionalrectposition in pixels of the currently dragged items (for overlap check)
+Optionalresizingtrue if we're live resizing
+Optionalskipnode to skip collision
+Optionalwwidget dimension width (default?: 1)
+Optionalxwidget position x (default?: 0)
+Optionalywidget position y (default?: 0)
+internal runtime descriptions describing the widgets in the grid
+Optionalautoif true then x, y parameters will be ignored and widget will be places on the first available position (default?: false)
+Optionalcontenthtml to append inside as content
+Optionalelpointer back to HTML element
+Optionalgridpointer back to parent Grid instance
+Optionalhwidget dimension height (default?: 1)
+Optionalidvalue for gs-id stored on the widget (default?: undefined)
Optionallazytrue when widgets are only created when they scroll into view (visible)
+Optionallockedprevents being pushed by other widgets or api (default?: undefined = un-constrained), which is different from noMove (user action only)
Optionalmaxmaximum height allowed during resize/creation (default?: undefined = un-constrained)
+Optionalmaxmaximum width allowed during resize/creation (default?: undefined = un-constrained)
+Optionalminminimum height allowed during resize/creation (default?: undefined = un-constrained)
+Optionalminminimum width allowed during resize/creation (default?: undefined = un-constrained)
+Optionalnoprevents direct moving by the user (default?: undefined = un-constrained)
+Optionalnoprevent direct resizing by the user (default?: undefined = un-constrained)
+Optionalresizelocal override of GridStack.resizeToContentParent that specify the class to use for the parent (actual) vs child (wanted) height
+Optionalsizelocal (vs grid) override - see GridStackOptions. +Note: This also allow you to set a maximum h value (but user changeable during normal resizing) to prevent unlimited content from taking too much space (get scrollbar)
+Optionalsubactual sub-grid instance
+Optionalsuboptional nested grid options and list of children, which then turns into actual instance at runtime to get options from
+Optionalvisibleallow delay creation when visible
+Optionalwwidget dimension width (default?: 1)
+Optionalxwidget position x (default?: 0)
+Optionalywidget position y (default?: 0)
+Defines the options for a Grid
+OptionalacceptAccept widgets dragged from other grids or from outside (default: false). Can be:
true: will accept HTML elements having 'grid-stack-item' as class attributefalse: will not accept any external widgets// Accept all grid items
acceptWidgets: true
// Accept only items with specific class
acceptWidgets: 'my-draggable-item'
// Custom validation function
acceptWidgets: (el) => {
return el.getAttribute('data-accept') === 'true';
}
+
+
+http://gridstack.github.io/gridstack.js/demo/two.html for complete example
+Optionalalwayspossible values (default: mobile) - does not apply to non-resizable widgets
+false the resizing handles are only shown while hovering over a widget
+true the resizing handles are always shown
+'mobile' if running on a mobile device, default to true (since there is no hovering per say), else false.
+See example
Optionalanimateturns animation on (default?: true)
+Optionalautoif false gridstack will not initialize existing items (default?: true)
+OptionalcellOne cell height (default: 'auto'). Can be:
+Note: % values don't work correctly - see demo/cell-height.html
+Optionalcellthrottle time delay (in ms) used when cellHeight='auto' to improve performance vs usability (default?: 100). +A value of 0 will make it instant at a cost of re-creating the CSS file at ever window resize event!
+Optionalcell(internal) unit for cellHeight (default? 'px') which is set when a string cellHeight with a unit is passed (ex: '10rem')
+Optionalchildrenlist of children item to create when calling load() or addGrid()
+Optionalclassadditional class on top of '.grid-stack' (which is required for our CSS) to differentiate this instance. +Note: only used by addGrid(), else your element should have the needed class
+Optionalcolumnnumber of columns (default?: 12). Note: IF you change this, CSS also have to change. See https://github.com/gridstack/gridstack.js#change-grid-columns. +Note: for nested grids, it is recommended to use 'auto' which will always match the container grid-item current width (in column) to keep inside and outside +items always the same. flag is NOT supported for regular non-nested grids.
+Optionalcolumnresponsive column layout for width:column behavior
+Optionaldisabledisallows dragging of widgets (default?: false)
+Optionaldisabledisallows resizing of widgets (default?: false).
+Optionaldraggableallows to override UI draggable options. (default?: { handle?: '.grid-stack-item-content', appendTo?: 'body' })
+Optionalenginethe type of engine to create (so you can subclass) default to GridStackEngine
+Optionalfloatenable floating widgets (default?: false) See example (http://gridstack.github.io/gridstack.js/demo/float.html)
+Optionalhandledraggable handle selector (default?: '.grid-stack-item-content')
+Optionalhandledraggable handle class (e.g. 'grid-stack-item-content'). If set 'handle' is ignored (default?: null)
+Optionalitemadditional widget class (default?: 'grid-stack-item')
+Optionallayoutre-layout mode when we're a subgrid and we are being resized. default to 'list'
+Optionallazytrue when widgets are only created when they scroll into view (visible)
+Optionalmargingap between grid item and content (default?: 10). This will set all 4 sides and support the CSS formats below +an integer (px) +a string with possible units (ex: '2em', '20px', '2rem') +string with space separated values (ex: '5px 10px 0 20px' for all 4 sides, or '5em 10em' for top/bottom and left/right pairs like CSS). +Note: all sides must have same units (last one wins, default px)
+OptionalmarginOptionalmarginOptionalmarginOptionalmarginOLD way to optionally set each side - use margin: '5px 10px 0 20px' instead. Used internally to store each side.
+Optionalmargin(internal) unit for margin (default? 'px') set when margin is set as string with unit (ex: 2rem')
Optionalmaxmaximum rows amount. Default? is 0 which means no maximum rows
+Optionalminminimum rows amount which is handy to prevent grid from collapsing when empty. Default is 0.
+When no set the min-height CSS attribute on the grid div (in pixels) can be used, which will round to the closest row.
OptionalnonceIf you are using a nonce-based Content Security Policy, pass your nonce here and
+GridStack will add it to the <style> elements it creates.
Optionalplaceholderclass for placeholder (default?: 'grid-stack-placeholder')
+Optionalplaceholderplaceholder default content (default?: '')
+Optionalremovableif true widgets could be removed by dragging outside of the grid. It could also be a selector string (ex: ".trash"), +in this case widgets will be removed by dropping them there (default?: false) +See example (http://gridstack.github.io/gridstack.js/demo/two.html)
+Optionalremovableallows to override UI removable options. (default?: { accept: '.grid-stack-item' })
+Optionalresizableallows to override UI resizable options. default is { handles: 'se', autoHide: true on desktop, false on mobile }
+Optionalrowfix grid number of rows. This is a shortcut of writing minRow:N, maxRow:N. (default 0 no constrain)
Optionalrtlif true turns grid to RTL. Possible values are true, false, 'auto' (default?: 'auto') +See example
+Optionalsizeset to true if all grid items (by default, but item can also override) height should be based on content size instead of WidgetItem.h to avoid v-scrollbars. +Note: this is still row based, not pixels, so it will use ceil(getBoundingClientRect().height / getCellHeight())
+Optionalstaticmakes grid static (default?: false). If true widgets are not movable/resizable.
+You don't even need draggable/resizable. A CSS class
+'grid-stack-static' is also added to the element.
OptionalstyleOptionalsubenable/disable the creation of sub-grids on the fly by dragging items completely
+over others (nest) vs partially (push). Forces DDDragOpt.pause=true to accomplish that.
Optionalsublist of differences in options for automatically created sub-grids under us (inside our grid-items)
+GridStack Widget creation options
+Optionalautoif true then x, y parameters will be ignored and widget will be places on the first available position (default?: false)
+Optionalcontenthtml to append inside as content
+Optionalhwidget dimension height (default?: 1)
+Optionalidvalue for gs-id stored on the widget (default?: undefined)
Optionallazytrue when widgets are only created when they scroll into view (visible)
+Optionallockedprevents being pushed by other widgets or api (default?: undefined = un-constrained), which is different from noMove (user action only)
Optionalmaxmaximum height allowed during resize/creation (default?: undefined = un-constrained)
+Optionalmaxmaximum width allowed during resize/creation (default?: undefined = un-constrained)
+Optionalminminimum height allowed during resize/creation (default?: undefined = un-constrained)
+Optionalminminimum width allowed during resize/creation (default?: undefined = un-constrained)
+Optionalnoprevents direct moving by the user (default?: undefined = un-constrained)
+Optionalnoprevent direct resizing by the user (default?: undefined = un-constrained)
+Optionalresizelocal override of GridStack.resizeToContentParent that specify the class to use for the parent (actual) vs child (wanted) height
+Optionalsizelocal (vs grid) override - see GridStackOptions. +Note: This also allow you to set a maximum h value (but user changeable during normal resizing) to prevent unlimited content from taking too much space (get scrollbar)
+Optionalsuboptional nested grid options and list of children, which then turns into actual instance at runtime to get options from
+Optionalwwidget dimension width (default?: 1)
+Optionalxwidget position x (default?: 0)
+Optionalywidget position y (default?: 0)
+Interface for HTML elements extended with drag & drop options. +Used to associate DD configuration with DOM elements.
+Method to update the options and return the DD implementation
+Configuration for responsive grid behavior.
+Defines how the grid responds to different screen sizes by changing column counts. +NOTE: Make sure to include the appropriate CSS (gridstack-extra.css) to support responsive behavior.
+Optionalbreakpointspecify if breakpoints are for window size or grid size (default:false = grid)
+Optionalbreakpointsexplicit width:column breakpoints instead of automatic 'columnWidth'. NOTE: make sure to have correct extra CSS to support this.
+Optionalcolumnmaximum number of columns allowed (default: 12). NOTE: make sure to have correct extra CSS to support this.
+Optionalcolumnwanted width to maintain (+-50%) to dynamically pick a column count. NOTE: make sure to have correct extra CSS to support this.
+Optionallayoutglobal re-layout mode when changing columns
+Optional callback function called during load() operations. +Allows custom handling of widget addition/removal for framework integration.
+The parent HTML element
+The widget definition
+True if adding, false if removing
+True if this is a grid operation
+The created/modified HTML element, or undefined
+Different layout options when changing the number of columns.
+These options control how widgets are repositioned when the grid column count changes. +Note: The new list may be partially filled if there's a cached layout for that size.
+Options:
+'list': Treat items as a sorted list, keeping them sequentially without resizing (unless too big)'compact': Similar to list, but uses compact() method to fill empty slots by reordering'moveScale': Scale and move items by the ratio of newColumnCount / oldColumnCount'move': Only move items, keep their sizes'scale': Only scale items, keep their positions'none': Leave items unchanged unless they don't fit in the new column countOptions for the compact() method to reclaim empty space.
+'list': Keep items in order, move them up sequentially'compact': Find truly empty spaces, may reorder items for optimal fitCallback function type for drag & drop events.
+The DOM event that triggered the callback
+The grid item element being dragged/dropped
+Optionalhelper: GridItemHTMLElementOptional helper element used during drag operations
+Drag & Drop options for drop targets. +Configures which elements can be dropped onto a grid.
+Keys for DD configuration options that can be set via the 'option' command.
+Drag & Drop operation types used throughout the DD system. +Can be control commands or configuration objects.
+Values for DD configuration options (numbers or strings with units).
+Type for event callback functions used in drag & drop operations. +Can return boolean to indicate if the event should continue propagation.
+Drop event handler that receives previous and new node states
+Type representing various ways to specify grid elements. +Can be a CSS selector string, GridItemHTMLElement (HTML element with GS variables when loaded).
+Element-specific event handler that receives event and affected element
+list of possible events, or space separated list of them
+General event handler that receives only the event
+Union type of all possible event handler types
+Node-based event handler that receives event and array of affected nodes
+Optional callback function for custom widget content rendering. +Called during load()/addWidget() to create custom content beyond plain text.
+The widget's content container element
+The widget definition with content and other properties
+Optional callback function for custom resize-to-content behavior. +Called when a widget needs to resize to fit its content.
+The grid item element to resize
+Optional callback function called during save() operations. +Allows adding custom data to the saved widget structure.
+The internal grid node
+The widget structure being saved (can be modified)
+Type representing values that can be either numbers or strings (e.g., dimensions with units). +Used for properties like width, height, margins that accept both numeric and string values.
+ConstDefault values for grid options - used during initialization and when saving out grid configuration. +These values are applied when options are not explicitly provided.
+Current version | v10.3.1
+Build interactive dashboards in minutes
+ + + + + + View on Github + ++ If you find this library useful, please donate via + PayPal + or + Venmo (adumesny) + and help support it! +
++ Workflow +
++ Gridstack.js is a modern pure Typescript library, with no external + dependencies, that can work with any framework. It comes bundled with an + Angular wrapper, and include many React|Vue examples (wrapper coming + soon) as well as others. +
+Pure Typescript
+React
+Vue
+And many more...
++ Features +
++ Gridstack.js is a modern Typescript library designed to help developers + create beautiful draggable, resizable, responsive layouts with just a + few lines of code. +
++ Craft responsive, mobile-friendly applications with ease. +
++ Intuitive interfaces with interactive components. +
++ Manage content dynamically from a sidebar for insertions and + deletions. +
++ Design adaptable and visually appealing web layouts. +
++ Easily preserve and revert to previous layouts. +
++ Drag items across multiple grids for sophisticated layout + management. +
++ Create and manipulate nested grids dynamically to any depth. +
++ Native Angular support, along with external bindings for Vue, React, + Ember, Knockout.js, and more. +
++ Demonstration +
++ Simple to use, configure, and customize. Drag and drop the items below + to try ! +
+ ++ Code +
++ Create your first interactive grid by copy-pasting the HTML+JS, as + seen below... +
+npm install gridstack
+
+ + Then, in your HTML file, include the following code... +
+
+<script src="node_modules/gridstack/dist/gridstack-all.js"></script>
+<link href="node_modules/gridstack/dist/gridstack.min.css" rel="stylesheet"/>
+<style type="text/css">
+ .grid-stack { background: #FAFAD2; }
+ .grid-stack-item-content { background-color: #18BC9C; }
+</style>
+
+<div class="grid-stack"></div>
+
+<script type="text/javascript">
+ var items = [
+ {content: 'my first widget'}, // will default to location (0,0) and 1x1
+ {w: 2, content: 'another longer widget!'} // will be placed next at (1,0) and 2x1
+ ];
+ var grid = GridStack.init();
+ grid.load(items);
+</script>
+
+
+ + ...and that's it! Drag, drop, and resize to your heart's content. + Looking for more complex examples? Check out the advanced example + below, the links in the nav bar, or our docs in + GitHub +
++ Demonstration +
+
+ A full control example with a trash can to remove widgets and a drag
+ in widget.
+
+
+ More complex examples are available to demonstrate the full power of
+ gridstack.js.
+
+ Drag and drop the items below to try!
+
+ Drag me into the dashboard! +
+Drop here to remove widget!
++ Articles +
++ Find out why developers everywhere are choosing gridstack.js for their + projects. +
++ Companies +
++ Discover the companies and projects that trust gridstack.js for their + applications. +
+ +...and many, many others.
++ We'd love to add your logo! Come join our + + + Slack community + + and let us know. +
+
Base widget class for GridStack Angular integration.
+