Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 12 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,17 +245,20 @@ For 4-column grid it should be:

and so on.

Better yet, here is a SASS code snippet which can make life much easier (Thanks to @ascendantofrain, [#81](https://github.com/gridstack/gridstack.js/issues/81) and @StefanM98, [#868](https://github.com/gridstack/gridstack.js/issues/868)) and you can use sites like [sassmeister.com](https://www.sassmeister.com/) to generate the CSS for you instead:
Better yet, here is a SASS code snippet, you can use sites like [sassmeister.com](https://www.sassmeister.com/) to generate the CSS for you instead:

```sass
.grid-stack > .grid-stack-item {
$gridstack-columns: 12;
$columns: 12;
@function fixed($float) {
@return calc(round($float * 1000) / 1000);
}
.grid-stack-#{$columns} > .grid-stack-item {

min-width: calc(100% / $gridstack-columns);
min-width: fixed(calc(100% / $columns));

@for $i from 0 through $gridstack-columns {
&[gs-w='#{$i}'] { width: (calc(100% / $gridstack-columns)) * $i; }
&[gs-x='#{$i}'] { left: (calc(100% / $gridstack-columns)) * $i; }
@for $i from 1 through $columns - 1 {
&[gs-x='#{$i}'] { left: fixed(calc(100% / $columns) * $i); }
&[gs-w='#{$i+1}'] { width: fixed(calc(100% / $columns) * ($i+1)); }
}
}
```
Expand Down Expand Up @@ -445,11 +448,12 @@ New addition, no API breakage per say. See release notes about creating sub-grid

## Migrating to v8

Possible breaking change if you use nested grid JSON format, or original Angular wrapper. Also target is now ES2020 (see release notes).
Possible breaking change if you use nested grid JSON format, or original Angular wrapper, or relied on specific CSS paths. Also target is now ES2020 (see release notes).
* `GridStackOptions.subGrid` -> `GridStackOptions.subGridOpts` rename
* We now have `GridStackWidget.subGridOpts` vs `GridStackNode.subGrid` (was `subGrid` with both types which is error prone)
* `GridStackOptions.addRemoveCB` -> `GridStack.addRemoveCB` is now global instead of grid option
* removed `GridStackOptions.dragInOptions` since `setupDragIn()`has it replaced since 4.0
* remove `GridStackOptions.minWidth` obsolete since 5.1, use `oneColumnSize` instead

# jQuery Application

Expand Down
11 changes: 4 additions & 7 deletions demo/demo.css
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,18 @@ h1 {
background: rgba(0, 255, 0, 0.1);
padding: 25px 0;
height: 100px;
text-align: center;
}
.sidebar .grid-stack-item {
display: inline-block;
position: relative;
width: 120px;
height: 50px;
border: 2px dashed green;
text-align: center;
line-height: 35px;
z-index: 10;
background: rgba(0, 255, 0, 0.1);
cursor: default;
display: inline-block;
}
.sidebar .grid-stack-item .grid-stack-item-content {
background: none;
width: 100%;
height: 100%;
}

/* make nested grid have slightly darker bg take almost all space (need some to tell them apart) so items inside can have similar to external size+margin */
Expand Down
4 changes: 4 additions & 0 deletions doc/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ Change log

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

## 8.0.2 TBD
* break: remove `GridStackOptions.minWidth` obsolete since 5.1, use `oneColumnSize` instead
* optimize: CSS files now even 25% smaller (after being halfed in 8.0.0) by removing `.grid-stack` prefix for anything already gs based, and 3 digit rounding.

## 8.0.1 (2023-04-29)
* feat: [#2275](https://github.com/gridstack/gridstack.js/issues/2275) `setupDragIn()` now can take an array or elements (in addition to selector string) and optional parent root (for shadow DOM support)
* fix: [#2234](https://github.com/gridstack/gridstack.js/issues/2234) `Utils.getElements('1')` (called by removeWidget() and others) now checks for digit 'selector' (becomes an id).
Expand Down
17 changes: 9 additions & 8 deletions src/gridstack-extra.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,22 @@
* default to generate [2-11] columns as 1 (oneColumnMode) and 12 (default) are in the main css
* Copyright (c) 2021 Alain Dumesny - see GridStack root license
*/

@use "sass:math";

$gridstack-columns-start: 2 !default;
$gridstack-columns: 11 !default;

@function fixed($float) {
@return calc(round($float * 1000) / 1000);
}

@mixin grid-stack-items($columns) {
.grid-stack.grid-stack-#{$columns} {
.grid-stack-#{$columns} {

> .grid-stack-item {
min-width: math.div(100%, $columns);
min-width: fixed(calc(100% / $columns));

@for $i from 1 through $columns {
&[gs-w='#{$i}'] { width: math.div(100%, $columns) * $i; }
&[gs-x='#{$i}'] { left: math.div(100%, $columns) * $i; }
@for $i from 1 through $columns - 1 {
&[gs-x='#{$i}'] { left: fixed(calc(100% / $columns) * $i); }
&[gs-w='#{$i+1}'] { width: fixed(calc(100% / $columns) * ($i+1)); }
}
}
}
Expand Down
207 changes: 107 additions & 100 deletions src/gridstack.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,137 +3,144 @@
* Copyright (c) 2021 Alain Dumesny - see GridStack root license
*/

@use "sass:math";

$gridstack-columns: 12 !default;
$columns: 12 !default;
$animation_speed: .3s !default;

@function fixed($float) {
@return calc(round($float * 1000) / 1000);
}

@mixin vendor($property, $value...){
-webkit-#{$property}: $value;
-moz-#{$property}: $value;
-ms-#{$property}: $value;
-o-#{$property}: $value;
// -webkit-#{$property}: $value;
// -moz-#{$property}: $value;
// -ms-#{$property}: $value;
// -o-#{$property}: $value;
#{$property}: $value;
}

:root .grid-stack-item > .ui-resizable-handle { filter: none; }

.grid-stack {
position: relative;
}

&.grid-stack-rtl {
direction: ltr;
> .grid-stack-item {
direction: rtl;
}
.grid-stack-rtl {
direction: ltr;
> .grid-stack-item {
direction: rtl;
}
}

.grid-stack-placeholder > .placeholder-content {
background-color: rgba(0,0,0,0.1);
margin: 0;
position: absolute;
width: auto;
z-index: 0 !important;
text-align: center;
}
.grid-stack-placeholder > .placeholder-content {
background-color: rgba(0,0,0,0.1);
margin: 0;
position: absolute;
width: auto;
z-index: 0 !important;
}

> .grid-stack-item {
min-width: math.div(100%, $gridstack-columns);
position: absolute;
padding: 0;
.grid-stack-item-content {
margin: 0;
position: absolute;
width: auto;
overflow-x: hidden;
overflow-y: auto;
}

> .grid-stack-item-content {
margin: 0;
position: absolute;
width: auto;
overflow-x: hidden;
overflow-y: auto;
}
.grid-stack-item {
position: absolute;
padding: 0;

> .ui-resizable-handle {
position: absolute;
font-size: 0.1px;
display: block;
-ms-touch-action: none;
touch-action: none;
}
> .ui-resizable-handle {
position: absolute;
font-size: 0.1px;
display: block;
-ms-touch-action: none;
touch-action: none;
}

&.ui-resizable-disabled > .ui-resizable-handle,
&.ui-resizable-autohide > .ui-resizable-handle { display: none; }
&.ui-resizable-disabled > .ui-resizable-handle,
&.ui-resizable-autohide > .ui-resizable-handle { display: none; }

> .ui-resizable-ne,
> .ui-resizable-nw,
> .ui-resizable-se,
> .ui-resizable-sw {
background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTYuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjE2cHgiIGhlaWdodD0iMTZweCIgdmlld0JveD0iMCAwIDUxMS42MjYgNTExLjYyNyIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNTExLjYyNiA1MTEuNjI3OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+CjxnPgoJPHBhdGggZD0iTTMyOC45MDYsNDAxLjk5NGgtMzYuNTUzVjEwOS42MzZoMzYuNTUzYzQuOTQ4LDAsOS4yMzYtMS44MDksMTIuODQ3LTUuNDI2YzMuNjEzLTMuNjE1LDUuNDIxLTcuODk4LDUuNDIxLTEyLjg0NSAgIGMwLTQuOTQ5LTEuODAxLTkuMjMxLTUuNDI4LTEyLjg1MWwtNzMuMDg3LTczLjA5QzI2NS4wNDQsMS44MDksMjYwLjc2LDAsMjU1LjgxMywwYy00Ljk0OCwwLTkuMjI5LDEuODA5LTEyLjg0Nyw1LjQyNCAgIGwtNzMuMDg4LDczLjA5Yy0zLjYxOCwzLjYxOS01LjQyNCw3LjkwMi01LjQyNCwxMi44NTFjMCw0Ljk0NiwxLjgwNyw5LjIyOSw1LjQyNCwxMi44NDVjMy42MTksMy42MTcsNy45MDEsNS40MjYsMTIuODUsNS40MjYgICBoMzYuNTQ1djI5Mi4zNThoLTM2LjU0MmMtNC45NTIsMC05LjIzNSwxLjgwOC0xMi44NSw1LjQyMWMtMy42MTcsMy42MjEtNS40MjQsNy45MDUtNS40MjQsMTIuODU0ICAgYzAsNC45NDUsMS44MDcsOS4yMjcsNS40MjQsMTIuODQ3bDczLjA4OSw3My4wODhjMy42MTcsMy42MTcsNy44OTgsNS40MjQsMTIuODQ3LDUuNDI0YzQuOTUsMCw5LjIzNC0xLjgwNywxMi44NDktNS40MjQgICBsNzMuMDg3LTczLjA4OGMzLjYxMy0zLjYyLDUuNDIxLTcuOTAxLDUuNDIxLTEyLjg0N2MwLTQuOTQ4LTEuODA4LTkuMjMyLTUuNDIxLTEyLjg1NCAgIEMzMzguMTQyLDQwMy44MDIsMzMzLjg1Nyw0MDEuOTk0LDMyOC45MDYsNDAxLjk5NHoiIGZpbGw9IiM2NjY2NjYiLz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8L3N2Zz4K);
background-repeat: no-repeat;
background-position: center;
}
> .ui-resizable-ne,
> .ui-resizable-nw,
> .ui-resizable-se,
> .ui-resizable-sw {
background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTYuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjE2cHgiIGhlaWdodD0iMTZweCIgdmlld0JveD0iMCAwIDUxMS42MjYgNTExLjYyNyIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNTExLjYyNiA1MTEuNjI3OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+CjxnPgoJPHBhdGggZD0iTTMyOC45MDYsNDAxLjk5NGgtMzYuNTUzVjEwOS42MzZoMzYuNTUzYzQuOTQ4LDAsOS4yMzYtMS44MDksMTIuODQ3LTUuNDI2YzMuNjEzLTMuNjE1LDUuNDIxLTcuODk4LDUuNDIxLTEyLjg0NSAgIGMwLTQuOTQ5LTEuODAxLTkuMjMxLTUuNDI4LTEyLjg1MWwtNzMuMDg3LTczLjA5QzI2NS4wNDQsMS44MDksMjYwLjc2LDAsMjU1LjgxMywwYy00Ljk0OCwwLTkuMjI5LDEuODA5LTEyLjg0Nyw1LjQyNCAgIGwtNzMuMDg4LDczLjA5Yy0zLjYxOCwzLjYxOS01LjQyNCw3LjkwMi01LjQyNCwxMi44NTFjMCw0Ljk0NiwxLjgwNyw5LjIyOSw1LjQyNCwxMi44NDVjMy42MTksMy42MTcsNy45MDEsNS40MjYsMTIuODUsNS40MjYgICBoMzYuNTQ1djI5Mi4zNThoLTM2LjU0MmMtNC45NTIsMC05LjIzNSwxLjgwOC0xMi44NSw1LjQyMWMtMy42MTcsMy42MjEtNS40MjQsNy45MDUtNS40MjQsMTIuODU0ICAgYzAsNC45NDUsMS44MDcsOS4yMjcsNS40MjQsMTIuODQ3bDczLjA4OSw3My4wODhjMy42MTcsMy42MTcsNy44OTgsNS40MjQsMTIuODQ3LDUuNDI0YzQuOTUsMCw5LjIzNC0xLjgwNywxMi44NDktNS40MjQgICBsNzMuMDg3LTczLjA4OGMzLjYxMy0zLjYyLDUuNDIxLTcuOTAxLDUuNDIxLTEyLjg0N2MwLTQuOTQ4LTEuODA4LTkuMjMyLTUuNDIxLTEyLjg1NCAgIEMzMzguMTQyLDQwMy44MDIsMzMzLjg1Nyw0MDEuOTk0LDMyOC45MDYsNDAxLjk5NHoiIGZpbGw9IiM2NjY2NjYiLz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8L3N2Zz4K);
background-repeat: no-repeat;
background-position: center;
}

> .ui-resizable-ne {
@include vendor(transform, translate(0, 10px) rotate(45deg));
}
> .ui-resizable-sw {
@include vendor(transform, rotate(45deg));
}
> .ui-resizable-ne {
@include vendor(transform, translate(0, 10px) rotate(45deg));
}
> .ui-resizable-sw {
@include vendor(transform, rotate(45deg));
}

> .ui-resizable-nw {
@include vendor(transform, translate(0, 10px) rotate(-45deg));
}
> .ui-resizable-se {
@include vendor(transform, rotate(-45deg));
}
> .ui-resizable-nw {
@include vendor(transform, translate(0, 10px) rotate(-45deg));
}
> .ui-resizable-se {
@include vendor(transform, rotate(-45deg));
}

> .ui-resizable-nw { cursor: nw-resize; width: 20px; height: 20px; top: 0; }
> .ui-resizable-n { cursor: n-resize; height: 10px; top: 0; left: 25px; right: 25px; }
> .ui-resizable-ne { cursor: ne-resize; width: 20px; height: 20px; top: 0; }
> .ui-resizable-e { cursor: e-resize; width: 10px; top: 15px; bottom: 15px; }
> .ui-resizable-se { cursor: se-resize; width: 20px; height: 20px;}
> .ui-resizable-s { cursor: s-resize; height: 10px; left: 25px; bottom: 0; right: 25px; }
> .ui-resizable-sw { cursor: sw-resize; width: 20px; height: 20px;}
> .ui-resizable-w { cursor: w-resize; width: 10px; top: 15px; bottom: 15px; }

&.ui-draggable-dragging {
&> .ui-resizable-handle {
display: none !important;
}
> .ui-resizable-nw { cursor: nw-resize; width: 20px; height: 20px; top: 0; }
> .ui-resizable-n { cursor: n-resize; height: 10px; top: 0; left: 25px; right: 25px; }
> .ui-resizable-ne { cursor: ne-resize; width: 20px; height: 20px; top: 0; }
> .ui-resizable-e { cursor: e-resize; width: 10px; top: 15px; bottom: 15px; }
> .ui-resizable-se { cursor: se-resize; width: 20px; height: 20px;}
> .ui-resizable-s { cursor: s-resize; height: 10px; left: 25px; bottom: 0; right: 25px; }
> .ui-resizable-sw { cursor: sw-resize; width: 20px; height: 20px;}
> .ui-resizable-w { cursor: w-resize; width: 10px; top: 15px; bottom: 15px; }

&.ui-draggable-dragging {
&> .ui-resizable-handle {
display: none !important;
}
}

&.ui-draggable-dragging,
&.ui-resizable-resizing {
z-index: 100;

@for $i from 0 through ($gridstack-columns - 1) {
&[gs-x='#{$i}'] { left: math.div(100%, $gridstack-columns) * $i; }
&[gs-w='#{$i + 1}'] { width: math.div(100%, $gridstack-columns) * ($i + 1); }
> .grid-stack-item-content {
box-shadow: 1px 4px 6px rgba(0, 0, 0, 0.2);
opacity: 0.8;
}
}

&.grid-stack-1>.grid-stack-item {
min-width: 100%;
&.ui-draggable-dragging {
will-change: left, top;
cursor: move;
}

&.grid-stack-animate,
&.grid-stack-animate .grid-stack-item {
@include vendor(transition, left $animation_speed, top $animation_speed, height $animation_speed, width $animation_speed);
&.ui-resizable-resizing {
will-change: width, height;
}
}

&.grid-stack-animate .grid-stack-item.ui-draggable-dragging,
&.grid-stack-animate .grid-stack-item.ui-resizable-resizing,
&.grid-stack-animate .grid-stack-item.grid-stack-placeholder{
@include vendor(transition, left 0s, top 0s, height 0s, width 0s);
}
.grid-stack-animate,
.grid-stack-animate .grid-stack-item {
@include vendor(transition, left $animation_speed, top $animation_speed, height $animation_speed, width $animation_speed);
}

.ui-draggable-dragging,
.ui-resizable-resizing {
z-index: 100;
.grid-stack-animate .grid-stack-item.ui-draggable-dragging,
.grid-stack-animate .grid-stack-item.ui-resizable-resizing,
.grid-stack-animate .grid-stack-item.grid-stack-placeholder{
@include vendor(transition, left 0s, top 0s, height 0s, width 0s);
}

.grid-stack-item[gs-x="0"] {
left: 0%;
}

> .grid-stack-item-content {
box-shadow: 1px 4px 6px rgba(0, 0, 0, 0.2);
opacity: 0.8;
.grid-stack-#{$columns} > .grid-stack-item {
min-width: fixed(calc(100% / $columns));
@for $i from 1 through ($columns - 1) {
&[gs-x='#{$i}'] { left: fixed(calc(100% / $columns) * $i); }
&[gs-w='#{$i + 1}'] { width: fixed(calc(100% / $columns) * ($i + 1)); }
}
}
.ui-draggable-dragging {
will-change: left, top;
cursor: move;

.grid-stack-1 > .grid-stack-item {
min-width: 100%;
}
.ui-resizable-resizing {
will-change: width, height;
}
11 changes: 1 addition & 10 deletions src/gridstack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,13 +270,6 @@ export class GridStack {
if (opts.column === 'auto') {
delete opts.column;
}
// 'minWidth' legacy support in 5.1
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
let anyOpts = opts as any;
if (anyOpts.minWidth !== undefined) {
opts.oneColumnSize = opts.oneColumnSize || anyOpts.minWidth;
delete anyOpts.minWidth;
}
// save original setting so we can restore on save
if (opts.alwaysShowResizeHandle !== undefined) {
(opts as InternalGridStackOptions)._alwaysShowResizeHandle = opts.alwaysShowResizeHandle;
Expand Down Expand Up @@ -386,9 +379,7 @@ export class GridStack {
this.setAnimation(this.opts.animate);

this._updateStyles();
if (this.opts.column != 12) {
this.el.classList.add('grid-stack-' + this.opts.column);
}
this.el.classList.add('grid-stack-' + this.opts.column);

// dynamic grids require pausing during drag to detect over to nest vs push
if (this.opts.subGridDynamic && !DDManager.pauseDrag) DDManager.pauseDrag = true;
Expand Down