@appnest/masonry-layout
Advanced tools
Comparing version 2.0.4 to 2.0.5
@@ -7,3 +7,3 @@ { | ||
"description": "Masonry layout web component. It places the slotted elements in the optimal position based\non the available vertical space, just like mason fitting stones in a wall.", | ||
"jsDoc": "/**\n * Masonry layout web component. It places the slotted elements in the optimal position based\n * on the available vertical space, just like mason fitting stones in a wall.\n * @example <masonry-layout><div class=\"item\"></div><div class=\"item\"></div></masonry-layout>\n * @csspart column - Each column of the masonry layout.\n * @csspart column-index - The specific column at the given index (eg. column-0 would target the first column and so on))\n * @slot - Items that should be distributed in the layout.\n */", | ||
"jsDoc": "/**\n * Masonry layout web component. It places the slotted elements in the optimal position based\n * on the available vertical space, just like mason fitting stones in a wall.\n * @example <masonry-layout><div class=\"item\"></div><div class=\"item\"></div></masonry-layout>\n * @csspart column - Each column of the masonry layout.\n * @csspart column-index - The specific column at the given index (eg. column-0 would target the first column and so on)\n * @slot - Items that should be distributed in the layout.\n */", | ||
"attributes": [ | ||
@@ -72,3 +72,3 @@ { | ||
"name": "column-index", | ||
"description": "The specific column at the given index (eg. column-0 would target the first column and so on))" | ||
"description": "The specific column at the given index (eg. column-0 would target the first column and so on)" | ||
}, | ||
@@ -75,0 +75,0 @@ { |
@@ -1,2 +0,2 @@ | ||
export declare const DEFAULT_MAX_COL_WIDTH = 400; | ||
export declare const DEFAULT_MAX_COL_WIDTH = 500; | ||
export declare const DEFAULT_COLS = "auto"; | ||
@@ -3,0 +3,0 @@ export declare const DEFAULT_DEBOUNCE_MS = 300; |
@@ -1,2 +0,2 @@ | ||
export const DEFAULT_MAX_COL_WIDTH = 400; | ||
export const DEFAULT_MAX_COL_WIDTH = 500; | ||
export const DEFAULT_COLS = "auto"; | ||
@@ -27,3 +27,5 @@ export const DEFAULT_DEBOUNCE_MS = 300; | ||
export function getColCount(totalWidth, cols, maxColWidth) { | ||
return isNaN(cols) ? Math.max(1, Math.floor(totalWidth / maxColWidth)) : cols; | ||
return isNaN(cols) | ||
? Math.max(1, Math.ceil(totalWidth / maxColWidth)) | ||
: cols; | ||
} | ||
@@ -30,0 +32,0 @@ /** |
@@ -21,3 +21,3 @@ declare type ResizeObserverEntries = { | ||
* @csspart column - Each column of the masonry layout. | ||
* @csspart column-index - The specific column at the given index (eg. column-0 would target the first column and so on)) | ||
* @csspart column-index - The specific column at the given index (eg. column-0 would target the first column and so on) | ||
* @slot - Items that should be distributed in the layout. | ||
@@ -24,0 +24,0 @@ */ |
@@ -15,3 +15,4 @@ import { COL_COUNT_CSS_VAR_NAME, debounce, DEFAULT_COLS, DEFAULT_DEBOUNCE_MS, DEFAULT_GAP_PX, DEFAULT_MAX_COL_WIDTH, ELEMENT_NODE_TYPE, findSmallestColIndex, GAP_CSS_VAR_NAME, getColCount, getNumberAttribute } from "./masonry-helpers"; | ||
.column { | ||
width: calc((100% / var(${COL_COUNT_CSS_VAR_NAME}, 1)) - var(${GAP_CSS_VAR_NAME}, ${DEFAULT_GAP_PX}px)); | ||
max-width: calc(100% / var(${COL_COUNT_CSS_VAR_NAME}, 1)); | ||
width: 100%; | ||
flex: 1; | ||
@@ -50,3 +51,3 @@ display: flex; | ||
* @csspart column - Each column of the masonry layout. | ||
* @csspart column-index - The specific column at the given index (eg. column-0 would target the first column and so on)) | ||
* @csspart column-index - The specific column at the given index (eg. column-0 would target the first column and so on) | ||
* @slot - Items that should be distributed in the layout. | ||
@@ -158,3 +159,3 @@ */ | ||
case "gap": | ||
this.style.setProperty(`${GAP_CSS_VAR_NAME}`, `${this.gap}px`); | ||
this.style.setProperty(GAP_CSS_VAR_NAME, `${this.gap}px`); | ||
break; | ||
@@ -224,3 +225,3 @@ } | ||
// Set the column count so we can compute the correct width of the columns | ||
this.style.setProperty(`${COL_COUNT_CSS_VAR_NAME}`, colCount.toString()); | ||
this.style.setProperty(COL_COUNT_CSS_VAR_NAME, colCount.toString()); | ||
// Commit the changes for ShadyCSS | ||
@@ -227,0 +228,0 @@ window.ShadyCSS && window.ShadyCSS.styleElement(this); |
{ | ||
"name": "@appnest/masonry-layout", | ||
"version": "2.0.4", | ||
"version": "2.0.5", | ||
"license": "MIT", | ||
@@ -51,4 +51,4 @@ "module": "index.js", | ||
"@appnest/readme": "^1.2.5", | ||
"@appnest/web-config": "0.4.33" | ||
"@appnest/web-config": "0.4.34" | ||
} | ||
} |
@@ -88,3 +88,3 @@ <h1 align="center">@appnest/masonry-layout</h1> | ||
The `maxcolwidth` specifies how many pixels a column can maximum have when the `cols` are set to `auto`. The default value is `400px`. | ||
The `maxcolwidth` specifies how many pixels a column can maximum have when the `cols` attribute is set to `auto`. The default value is `400px`. | ||
@@ -112,3 +112,3 @@ ```html | ||
If you want to force layout to can simply call the `layout()` function on the masonry layout. | ||
If you want to force layout to can call the `layout()` function on the masonry layout. | ||
@@ -157,13 +157,17 @@ ```js | ||
| `column` | Each column of the masonry layout. | | ||
| `column-index` | The specific column at the given index (eg. column-0 would target the first column and so on)) | | ||
| `column-index` | The specific column at the given index (eg. column-0 would target the first column and so on) | | ||
[![-----------------------------------------------------](https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png)](#resizeobserver) | ||
[![-----------------------------------------------------](https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png)](#support-for-old-browsers) | ||
## ➤ ResizeObserver | ||
## ➤ Support for old browsers | ||
You might want to polyfill the `ResizeObserver`. The observer in the element makes sure to distribute the items whenever the size of the grid changes. If this is not polyfilled you will have to call the `layout()` function yourself when the height of the grid changes. If no `ResizeObserver` can be found on the `window` object it will instead re-distribute items when the size of the window changes. | ||
If you are going to support older browsers that doesn't support [Custom Elements](https://caniuse.com/#search=Custom%20Elements), [Shadow Dom](https://caniuse.com/#search=shadow%20root) or [ResizeObservers](https://caniuse.com/#search=resize%20observer) you should polyfill the features. You can do this very easily by using [the brilliant polfiller service](https://github.com/wessberg/polyfiller). This can be done in one line of code by adding the following to your `index.html` before you import the `masonry-layout`. | ||
```html | ||
<script crossorigin src="https://polyfill.app/api/polyfill?features=es,template,shadow-dom,custom-elements,resizeobserver"></script> | ||
``` | ||
[![-----------------------------------------------------](https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png)](#license) | ||
@@ -173,3 +177,2 @@ | ||
Licensed under [MIT](https://opensource.org/licenses/MIT). | ||
Licensed under [MIT](https://opensource.org/licenses/MIT). |
@@ -12,3 +12,3 @@ declare type ResizeObserverEntries = { | ||
* @csspart column - Each column of the masonry layout. | ||
* @csspart column-index - The specific column at the given index (eg. column-0 would target the first column and so on)) | ||
* @csspart column-index - The specific column at the given index (eg. column-0 would target the first column and so on) | ||
* @slot - Items that should be distributed in the layout. | ||
@@ -15,0 +15,0 @@ */ |
@@ -1,1 +0,1 @@ | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t=t||self)["masonry-layout"]={})}(this,(function(t){"use strict";const e=400,n="auto",o=300,s=24,i="--_masonry-layout-col-count",l="--_masonry-layout-gap",r=1,a=new Map;function h(t,e,n){const o=parseFloat(t.getAttribute(e)||"");return isNaN(o)?n:o}function c(t,e,n){return isNaN(e)?Math.max(1,Math.floor(t/n)):e}function d(t){let e=0,n=1/0;return t.forEach((t,o)=>{t<n&&(n=t,e=o)}),e}const u=document.createElement("template");u.innerHTML=`\n <style>\n :host {\n display: flex;\n align-items: flex-start;\n justify-content: stretch;\n }\n\n .column {\n width: calc((100% / var(${i}, 1)) - var(${l}, ${s}px));\n flex: 1;\n display: flex;\n flex-direction: column;\n }\n\n .column:not(:last-child) {\n margin-right: var(${l}, ${s}px);\n }\n\n .column ::slotted(*) {\n margin-bottom: var(${l}, ${s}px);\n box-sizing: border-box;\n width: 100%;\n }\n\n /* Hide the items that has not yet found the correct slot */\n #unset-items {\n opacity: 0;\n position: absolute;\n pointer-events: none;\n }\n </style>\n <div id="unset-items">\n <slot></slot>\n </div>\n`,window.ShadyCSS&&window.ShadyCSS.prepareTemplateStyles(u,"masonry-layout");class m extends HTMLElement{constructor(){super(),this.debounceId=`layout_${Math.random()}`,this.ro=void 0,this.currentRequestAnimationFrameCallback=void 0,this.attachShadow({mode:"open"}).appendChild(u.content.cloneNode(!0)),this.onSlotChange=this.onSlotChange.bind(this),this.onResize=this.onResize.bind(this),this.layout=this.layout.bind(this),this.$unsetElementsSlot=this.shadowRoot.querySelector("#unset-items > slot")}static get observedAttributes(){return["maxcolwidth","gap","cols"]}set maxColWidth(t){this.setAttribute("maxcolwidth",t.toString())}get maxColWidth(){return h(this,"maxcolwidth",e)}set cols(t){this.setAttribute("cols",t.toString())}get cols(){return h(this,"cols",n)}set gap(t){this.setAttribute("gap",t.toString())}get gap(){return h(this,"gap",s)}set debounce(t){this.setAttribute("debounce",t.toString())}get debounce(){return h(this,"debounce",o)}get $columns(){return Array.from(this.shadowRoot.querySelectorAll(".column"))}connectedCallback(){this.$unsetElementsSlot.addEventListener("slotchange",this.onSlotChange),"ResizeObserver"in window?(this.ro=new ResizeObserver(this.onResize),this.ro.observe(this)):window.addEventListener("resize",this.onResize)}disconnectedCallback(){this.$unsetElementsSlot.removeEventListener("slotchange",this.onSlotChange),window.removeEventListener("resize",this.onResize),null!=this.ro&&this.ro.unobserve(this)}attributeChangedCallback(t){switch(t){case"gap":this.style.setProperty(`${l}`,`${this.gap}px`)}this.scheduleLayout()}onSlotChange(){(this.$unsetElementsSlot.assignedNodes()||[]).filter(t=>t.nodeType===r).length>0&&this.layout()}onResize(t){const{width:e}=null!=t&&Array.isArray(t)&&t.length>0?t[0].contentRect:{width:this.offsetWidth};c(e,this.cols,this.maxColWidth)!==this.$columns.length&&this.scheduleLayout()}renderCols(t){const e=this.$columns;if(e.length!==t){for(const t of e)t.parentNode&&t.parentNode.removeChild(t);for(let e=0;e<t;e++){const t=document.createElement("div");t.classList.add("column"),t.setAttribute("part",`column column-${e}`);const n=document.createElement("slot");n.setAttribute("name",e.toString()),t.appendChild(n),this.shadowRoot.appendChild(t)}this.style.setProperty(`${i}`,t.toString()),window.ShadyCSS&&window.ShadyCSS.styleElement(this)}}scheduleLayout(t=this.debounce){!function(t,e,n){const o=a.get(n);null!=o&&window.clearTimeout(o),a.set(n,window.setTimeout(t,e))}(this.layout,t,this.debounceId)}layout(){null!=this.currentRequestAnimationFrameCallback&&window.cancelAnimationFrame(this.currentRequestAnimationFrameCallback),this.currentRequestAnimationFrameCallback=requestAnimationFrame(()=>{const t=this.gap,e=Array.from(this.children).filter(t=>t.nodeType===r),n=c(this.offsetWidth,this.cols,this.maxColWidth),o=Array(n).fill(0),s=[];for(const n of e){const e=n.getBoundingClientRect().height;let i=d(o);o[i]+=e+t;const l=i.toString();n.slot!==l&&s.push(()=>n.slot=l)}for(const t of s)t();this.renderCols(n),window.ShadyCSS&&window.ShadyCSS.styleElement(this)})}}customElements.define("masonry-layout",m),t.MasonryLayout=m,Object.defineProperty(t,"__esModule",{value:!0})})); | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t=t||self)["masonry-layout"]={})}(this,(function(t){"use strict";const e=500,n="auto",o=300,s=24,i="--_masonry-layout-col-count",l="--_masonry-layout-gap",r=1,a=new Map;function h(t,e,n){const o=parseFloat(t.getAttribute(e)||"");return isNaN(o)?n:o}function c(t,e,n){return isNaN(e)?Math.max(1,Math.ceil(t/n)):e}function d(t){let e=0,n=1/0;return t.forEach((t,o)=>{t<n&&(n=t,e=o)}),e}const u=document.createElement("template");u.innerHTML=`\n <style>\n :host {\n display: flex;\n align-items: flex-start;\n justify-content: stretch;\n }\n\n .column {\n\t max-width: calc(100% / var(${i}, 1));\n\t width: 100%;\n flex: 1;\n display: flex;\n flex-direction: column;\n }\n\n .column:not(:last-child) {\n margin-right: var(${l}, ${s}px);\n }\n\n .column ::slotted(*) {\n margin-bottom: var(${l}, ${s}px);\n box-sizing: border-box;\n width: 100%;\n }\n\n /* Hide the items that has not yet found the correct slot */\n #unset-items {\n opacity: 0;\n position: absolute;\n pointer-events: none;\n }\n </style>\n <div id="unset-items">\n <slot></slot>\n </div>\n`,window.ShadyCSS&&window.ShadyCSS.prepareTemplateStyles(u,"masonry-layout");class m extends HTMLElement{constructor(){super(),this.debounceId=`layout_${Math.random()}`,this.ro=void 0,this.currentRequestAnimationFrameCallback=void 0,this.attachShadow({mode:"open"}).appendChild(u.content.cloneNode(!0)),this.onSlotChange=this.onSlotChange.bind(this),this.onResize=this.onResize.bind(this),this.layout=this.layout.bind(this),this.$unsetElementsSlot=this.shadowRoot.querySelector("#unset-items > slot")}static get observedAttributes(){return["maxcolwidth","gap","cols"]}set maxColWidth(t){this.setAttribute("maxcolwidth",t.toString())}get maxColWidth(){return h(this,"maxcolwidth",e)}set cols(t){this.setAttribute("cols",t.toString())}get cols(){return h(this,"cols",n)}set gap(t){this.setAttribute("gap",t.toString())}get gap(){return h(this,"gap",s)}set debounce(t){this.setAttribute("debounce",t.toString())}get debounce(){return h(this,"debounce",o)}get $columns(){return Array.from(this.shadowRoot.querySelectorAll(".column"))}connectedCallback(){this.$unsetElementsSlot.addEventListener("slotchange",this.onSlotChange),"ResizeObserver"in window?(this.ro=new ResizeObserver(this.onResize),this.ro.observe(this)):window.addEventListener("resize",this.onResize)}disconnectedCallback(){this.$unsetElementsSlot.removeEventListener("slotchange",this.onSlotChange),window.removeEventListener("resize",this.onResize),null!=this.ro&&this.ro.unobserve(this)}attributeChangedCallback(t){switch(t){case"gap":this.style.setProperty(l,`${this.gap}px`)}this.scheduleLayout()}onSlotChange(){(this.$unsetElementsSlot.assignedNodes()||[]).filter(t=>t.nodeType===r).length>0&&this.layout()}onResize(t){const{width:e}=null!=t&&Array.isArray(t)&&t.length>0?t[0].contentRect:{width:this.offsetWidth};c(e,this.cols,this.maxColWidth)!==this.$columns.length&&this.scheduleLayout()}renderCols(t){const e=this.$columns;if(e.length!==t){for(const t of e)t.parentNode&&t.parentNode.removeChild(t);for(let e=0;e<t;e++){const t=document.createElement("div");t.classList.add("column"),t.setAttribute("part",`column column-${e}`);const n=document.createElement("slot");n.setAttribute("name",e.toString()),t.appendChild(n),this.shadowRoot.appendChild(t)}this.style.setProperty(i,t.toString()),window.ShadyCSS&&window.ShadyCSS.styleElement(this)}}scheduleLayout(t=this.debounce){!function(t,e,n){const o=a.get(n);null!=o&&window.clearTimeout(o),a.set(n,window.setTimeout(t,e))}(this.layout,t,this.debounceId)}layout(){null!=this.currentRequestAnimationFrameCallback&&window.cancelAnimationFrame(this.currentRequestAnimationFrameCallback),this.currentRequestAnimationFrameCallback=requestAnimationFrame(()=>{const t=this.gap,e=Array.from(this.children).filter(t=>t.nodeType===r),n=c(this.offsetWidth,this.cols,this.maxColWidth),o=Array(n).fill(0),s=[];for(const n of e){const e=n.getBoundingClientRect().height;let i=d(o);o[i]+=e+t;const l=i.toString();n.slot!==l&&s.push(()=>n.slot=l)}for(const t of s)t();this.renderCols(n),window.ShadyCSS&&window.ShadyCSS.styleElement(this)})}}customElements.define("masonry-layout",m),t.MasonryLayout=m,Object.defineProperty(t,"__esModule",{value:!0})})); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
44359
672
174