diff --git a/README.md b/README.md index 4f5d4a84a..ef55f3fa8 100644 --- a/README.md +++ b/README.md @@ -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)); } } } ``` @@ -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 diff --git a/demo/demo.css b/demo/demo.css index bbb5c1884..66f47a3e1 100644 --- a/demo/demo.css +++ b/demo/demo.css @@ -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 */ diff --git a/doc/CHANGES.md b/doc/CHANGES.md index 89cfaf77d..1c3886696 100644 --- a/doc/CHANGES.md +++ b/doc/CHANGES.md @@ -84,6 +84,10 @@ Change log +## 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). diff --git a/src/gridstack-extra.scss b/src/gridstack-extra.scss index d663d2055..52f5f6d84 100644 --- a/src/gridstack-extra.scss +++ b/src/gridstack-extra.scss @@ -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)); } } } } diff --git a/src/gridstack.scss b/src/gridstack.scss index c3ac946a5..74a6f20f6 100644 --- a/src/gridstack.scss +++ b/src/gridstack.scss @@ -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; -} \ No newline at end of file diff --git a/src/gridstack.ts b/src/gridstack.ts index f51e11d35..e087cf022 100644 --- a/src/gridstack.ts +++ b/src/gridstack.ts @@ -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; @@ -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;