UNPKG

grid-layout-plus-no-pnpm

Version:

<p align="center"> <a href="https://grid-layout-plus.netlify.app/" target="_blank" rel="noopener noreferrer"> <img src="./docs/public/grid-layout-plus.svg" width="180" style="width: 120px;" /> </a> </p>

1 lines 24.4 kB
{"version":3,"file":"common.mjs","sources":["../../src/helpers/common.ts"],"sourcesContent":["import type { InjectionKey } from 'vue'\r\nimport type { EventEmitter } from '@vexip-ui/utils'\r\nimport type { LayoutItem, Layout, LayoutInstance } from './types'\r\n\r\nexport const LAYOUT_KEY = Symbol('LAYOUT_KEY') as InjectionKey<LayoutInstance>\r\nexport const EMITTER_KEY = Symbol('EMITTER_KEY') as InjectionKey<EventEmitter>\r\n\r\n/**\r\n * Return the bottom coordinate of the layout.\r\n *\r\n * @param layout Layout array.\r\n * @return Bottom coordinate.\r\n */\r\nexport function bottom(layout: Layout): number {\r\n let max = 0\r\n let bottomY\r\n for (let i = 0, len = layout.length; i < len; i++) {\r\n bottomY = layout[i].y + layout[i].h\r\n if (bottomY > max) max = bottomY\r\n }\r\n return max\r\n}\r\n\r\nexport function cloneLayout(layout: Layout): Layout {\r\n const newLayout = Array(layout.length)\r\n for (let i = 0, len = layout.length; i < len; i++) {\r\n newLayout[i] = cloneLayoutItem(layout[i])\r\n }\r\n return newLayout\r\n}\r\n\r\n// Fast path to cloning, since this is monomorphic\r\nexport function cloneLayoutItem(layoutItem: LayoutItem): LayoutItem {\r\n // return JSON.parse(JSON.stringify(layoutItem))\r\n return { ...layoutItem }\r\n}\r\n\r\n/**\r\n * Given two layoutitems, check if they collide.\r\n *\r\n * @return True if colliding.\r\n */\r\nexport function collides(l1: LayoutItem, l2: LayoutItem): boolean {\r\n if (l1 === l2) return false // same element\r\n if (l1.x + l1.w <= l2.x) return false // l1 is left of l2\r\n if (l1.x >= l2.x + l2.w) return false // l1 is right of l2\r\n if (l1.y + l1.h <= l2.y) return false // l1 is above l2\r\n if (l1.y >= l2.y + l2.h) return false // l1 is below l2\r\n return true // boxes overlap\r\n}\r\n\r\n/**\r\n * Given a layout, compact it. This involves going down each y coordinate and removing gaps\r\n * between items.\r\n *\r\n * @param layout Layout.\r\n * @param verticalCompact Whether or not to compact the layout vertically.\r\n * @param minPositions\r\n * @return Compacted Layout.\r\n */\r\nexport function compact(layout: Layout, verticalCompact?: boolean, minPositions?: any): Layout {\r\n // Statics go in the compareWith array right away so items flow around them.\r\n const compareWith = getStatics(layout)\r\n // We go through the items by row and column.\r\n const sorted = sortLayoutItemsByRowCol(layout)\r\n // Holding for new items.\r\n const out: Layout = Array(layout.length)\r\n\r\n for (let i = 0, len = sorted.length; i < len; i++) {\r\n let l = sorted[i]\r\n\r\n // Don't move static elements\r\n if (!l.static) {\r\n l = compactItem(compareWith, l, verticalCompact, minPositions)\r\n\r\n // Add to comparison array. We only collide with items before this one.\r\n // Statics are already in this array.\r\n compareWith.push(l)\r\n }\r\n\r\n // Add to output array to make sure they still come out in the right order.\r\n out[layout.indexOf(l)] = l\r\n\r\n // Clear moved flag, if it exists.\r\n l.moved = false\r\n }\r\n\r\n return out\r\n}\r\n\r\n/**\r\n * Compact an item in the layout.\r\n */\r\nexport function compactItem(\r\n compareWith: Layout,\r\n l: LayoutItem,\r\n verticalCompact?: boolean,\r\n minPositions?: any\r\n): LayoutItem {\r\n if (verticalCompact) {\r\n // Move the element up as far as it can go without colliding.\r\n while (l.y > 0 && !getFirstCollision(compareWith, l)) {\r\n l.y--\r\n }\r\n } else if (minPositions) {\r\n const minY = minPositions[l.i].y\r\n while (l.y > minY && !getFirstCollision(compareWith, l)) {\r\n l.y--\r\n }\r\n }\r\n\r\n // Move it down, and keep moving it down if it's colliding.\r\n let collides\r\n while ((collides = getFirstCollision(compareWith, l))) {\r\n l.y = collides.y + collides.h\r\n }\r\n return l\r\n}\r\n\r\n/**\r\n * Given a layout, make sure all elements fit within its bounds.\r\n *\r\n * @param layout Layout array.\r\n * @param bounds Number of columns.\r\n */\r\nexport function correctBounds(layout: Layout, bounds: { cols: number }): Layout {\r\n const collidesWith = getStatics(layout)\r\n for (let i = 0, len = layout.length; i < len; i++) {\r\n const l = layout[i]\r\n // Overflows right\r\n if (l.x + l.w > bounds.cols) l.x = bounds.cols - l.w\r\n // Overflows left\r\n if (l.x < 0) {\r\n l.x = 0\r\n l.w = bounds.cols\r\n }\r\n if (!l.static) collidesWith.push(l)\r\n else {\r\n // If this is static and collides with other statics, we must move it down.\r\n // We have to do something nicer than just letting them overlap.\r\n while (getFirstCollision(collidesWith, l)) {\r\n l.y++\r\n }\r\n }\r\n }\r\n return layout\r\n}\r\n\r\n/**\r\n * Get a layout item by ID. Used so we can override later on if necessary.\r\n *\r\n * @param layout Layout array.\r\n * @param id ID\r\n * @return Item at ID.\r\n */\r\nexport function getLayoutItem(layout: Layout, id: number | string): LayoutItem | undefined {\r\n for (let i = 0, len = layout.length; i < len; i++) {\r\n if (layout[i].i === id) return layout[i]\r\n }\r\n}\r\n\r\n/**\r\n * Returns the first item this layout collides with.\r\n * It doesn't appear to matter which order we approach this from, although\r\n * perhaps that is the wrong thing to do.\r\n *\r\n * @param {Object} layoutItem Layout item.\r\n * @return {Object|undefined} A colliding layout item, or undefined.\r\n */\r\nexport function getFirstCollision(layout: Layout, layoutItem: LayoutItem): LayoutItem | undefined {\r\n for (let i = 0, len = layout.length; i < len; i++) {\r\n if (collides(layout[i], layoutItem)) return layout[i]\r\n }\r\n}\r\n\r\nexport function getAllCollisions(layout: Layout, layoutItem: LayoutItem): Array<LayoutItem> {\r\n return layout.filter(l => collides(l, layoutItem))\r\n}\r\n\r\n/**\r\n * Get all static elements.\r\n * @param layout Array of layout objects.\r\n * @return Array of static layout items..\r\n */\r\nexport function getStatics(layout: Layout): Array<LayoutItem> {\r\n return layout.filter(l => l.static)\r\n}\r\n\r\n/**\r\n * Move an element. Responsible for doing cascading movements of other elements.\r\n *\r\n * @param layout Full layout to modify.\r\n * @param layoutItem element to move.\r\n * @param x X position in grid units.\r\n * @param y Y position in grid units.\r\n * @param isUserAction If true, designates that the item we're moving is\r\n * being dragged/resized by th euser.\r\n */\r\nexport function moveElement(\r\n layout: Layout,\r\n layoutItem: LayoutItem,\r\n x?: number,\r\n y?: number,\r\n isUserAction = false,\r\n preventCollision = false\r\n): Layout {\r\n if (layoutItem.static) return layout\r\n\r\n const oldX = layoutItem.x\r\n const oldY = layoutItem.y\r\n\r\n const movingUp = y && layoutItem.y > y\r\n // This is quite a bit faster than extending the object\r\n if (typeof x === 'number') layoutItem.x = x\r\n if (typeof y === 'number') layoutItem.y = y\r\n layoutItem.moved = true\r\n\r\n // If this collides with anything, move it.\r\n // When doing this comparison, we have to sort the items we compare with\r\n // to ensure, in the case of multiple collisions, that we're getting the\r\n // nearest collision.\r\n let sorted = sortLayoutItemsByRowCol(layout)\r\n if (movingUp) sorted = sorted.reverse()\r\n const collisions = getAllCollisions(sorted, layoutItem)\r\n\r\n if (preventCollision && collisions.length) {\r\n layoutItem.x = oldX\r\n layoutItem.y = oldY\r\n layoutItem.moved = false\r\n return layout\r\n }\r\n\r\n // Move each item that collides away from this element.\r\n for (let i = 0, len = collisions.length; i < len; i++) {\r\n const collision = collisions[i]\r\n\r\n // Short circuit so we can't infinite loop\r\n if (collision.moved) continue\r\n\r\n // This makes it feel a bit more precise by waiting to swap for just a bit when moving up.\r\n if (layoutItem.y > collision.y && layoutItem.y - collision.y > collision.h / 4) continue\r\n\r\n // Don't move static items - we have to move *this* element away\r\n if (collision.static) {\r\n layout = moveElementAwayFromCollision(layout, collision, layoutItem, isUserAction)\r\n } else {\r\n layout = moveElementAwayFromCollision(layout, layoutItem, collision, isUserAction)\r\n }\r\n }\r\n\r\n return layout\r\n}\r\n\r\n/**\r\n * This is where the magic needs to happen - given a collision, move an element away from the collision.\r\n * We attempt to move it up if there's room, otherwise it goes below.\r\n *\r\n * @param layout Full layout to modify.\r\n * @param collidesWith Layout item we're colliding with.\r\n * @param itemToMove Layout item we're moving.\r\n * @param isUserAction If true, designates that the item we're moving is being dragged/resized\r\n * by the user.\r\n */\r\nexport function moveElementAwayFromCollision(\r\n layout: Layout,\r\n collidesWith: LayoutItem,\r\n itemToMove: LayoutItem,\r\n isUserAction?: boolean\r\n): Layout {\r\n const preventCollision = false // we're already colliding\r\n // If there is enough space above the collision to put this element, move it there.\r\n // We only do this on the main collision as this can get funky in cascades and cause\r\n // unwanted swapping behavior.\r\n if (isUserAction) {\r\n // Make a mock item so we don't modify the item here, only modify in moveElement.\r\n const fakeItem: LayoutItem = {\r\n x: itemToMove.x,\r\n y: itemToMove.y,\r\n w: itemToMove.w,\r\n h: itemToMove.h,\r\n i: '-1'\r\n }\r\n fakeItem.y = Math.max(collidesWith.y - itemToMove.h, 0)\r\n if (!getFirstCollision(layout, fakeItem)) {\r\n return moveElement(layout, itemToMove, undefined, fakeItem.y, preventCollision)\r\n }\r\n }\r\n\r\n // Previously this was optimized to move below the collision directly, but this can cause problems\r\n // with cascading moves, as an item may actually leapflog a collision and cause a reversal in order.\r\n return moveElement(layout, itemToMove, undefined, itemToMove.y + 1, preventCollision)\r\n}\r\n\r\n/**\r\n * Helper to convert a number to a percentage string.\r\n *\r\n * @param num Any number\r\n * @return That number as a percentage.\r\n */\r\nexport function perc(num: number): string {\r\n return num * 100 + '%'\r\n}\r\n\r\nexport function setTransform(top: number, left: number, width: number, height: number) {\r\n // Replace unitless items with px\r\n const translate = 'translate3d(' + left + 'px,' + top + 'px, 0)'\r\n return {\r\n transform: translate,\r\n WebkitTransform: translate,\r\n MozTransform: translate,\r\n msTransform: translate,\r\n OTransform: translate,\r\n width: width + 'px',\r\n height: height + 'px',\r\n position: 'absolute'\r\n }\r\n}\r\n/**\r\n * Just like the setTransform method, but instead it will return a negative value of right.\r\n *\r\n * @param top\r\n * @param right\r\n * @param width\r\n * @param height\r\n * @returns {{transform: string, WebkitTransform: string, MozTransform: string, msTransform: string, OTransform: string, width: string, height: string, position: string}}\r\n */\r\nexport function setTransformRtl(top: number, right: number, width: number, height: number) {\r\n // Replace unitless items with px\r\n const translate = 'translate3d(' + right * -1 + 'px,' + top + 'px, 0)'\r\n return {\r\n transform: translate,\r\n WebkitTransform: translate,\r\n MozTransform: translate,\r\n msTransform: translate,\r\n OTransform: translate,\r\n width: width + 'px',\r\n height: height + 'px',\r\n position: 'absolute'\r\n }\r\n}\r\n\r\nexport function setTopLeft(top: number, left: number, width: number, height: number) {\r\n return {\r\n top: top + 'px',\r\n left: left + 'px',\r\n width: width + 'px',\r\n height: height + 'px',\r\n position: 'absolute'\r\n }\r\n}\r\n/**\r\n * Just like the setTopLeft method, but instead, it will return a right property instead of left.\r\n *\r\n * @param top\r\n * @param right\r\n * @param width\r\n * @param height\r\n * @returns position style\r\n */\r\nexport function setTopRight(top: number, right: number, width: number, height: number) {\r\n return {\r\n top: top + 'px',\r\n right: right + 'px',\r\n width: width + 'px',\r\n height: height + 'px',\r\n position: 'absolute'\r\n }\r\n}\r\n\r\n/**\r\n * Get layout items sorted from top left to right and down.\r\n *\r\n * @return Layout, sorted static items first.\r\n */\r\nexport function sortLayoutItemsByRowCol(layout: Layout): Layout {\r\n return Array.from(layout).sort(function (a, b) {\r\n if (a.y === b.y && a.x === b.x) {\r\n return 0\r\n }\r\n\r\n if (a.y > b.y || (a.y === b.y && a.x > b.x)) {\r\n return 1\r\n }\r\n\r\n return -1\r\n })\r\n}\r\n\r\n/**\r\n * Validate a layout. Throws errors.\r\n *\r\n * @param layout Array of layout items.\r\n * @param contextName Context name for errors.\r\n * @throw Validation error.\r\n */\r\nexport function validateLayout(layout: Layout, contextName?: string): void {\r\n contextName = contextName || 'Layout'\r\n const subProps = ['x', 'y', 'w', 'h']\r\n const keyArr = []\r\n if (!Array.isArray(layout)) throw new Error(contextName + ' must be an array!')\r\n for (let i = 0, len = layout.length; i < len; i++) {\r\n const item = layout[i]\r\n for (let j = 0; j < subProps.length; j++) {\r\n if (typeof (item as any)[subProps[j]] !== 'number') {\r\n throw new Error(\r\n 'VueGridLayout: ' + contextName + '[' + i + '].' + subProps[j] + ' must be a number!'\r\n )\r\n }\r\n }\r\n\r\n if (item.i === undefined || item.i === null) {\r\n throw new Error('VueGridLayout: ' + contextName + '[' + i + '].i cannot be null!')\r\n }\r\n\r\n if (typeof item.i !== 'number' && typeof item.i !== 'string') {\r\n throw new Error('VueGridLayout: ' + contextName + '[' + i + '].i must be a string or number!')\r\n }\r\n\r\n if (keyArr.indexOf(item.i) >= 0) {\r\n throw new Error('VueGridLayout: ' + contextName + '[' + i + '].i must be unique!')\r\n }\r\n keyArr.push(item.i)\r\n\r\n if (item.static !== undefined && typeof item.static !== 'boolean') {\r\n throw new Error('VueGridLayout: ' + contextName + '[' + i + '].static must be a boolean!')\r\n }\r\n }\r\n}\r\n\r\n// Flow can't really figure this out, so we just use Object\r\nexport function autoBindHandlers(\r\n el: Record<string, (...args: any[]) => any>,\r\n fns: Array<string>\r\n): void {\r\n fns.forEach(key => (el[key] = el[key].bind(el)))\r\n}\r\n\r\n/**\r\n * Convert a JS object to CSS string. Similar to React's output of CSS.\r\n * @param obj\r\n * @returns\r\n */\r\nexport function createMarkup(obj: Record<string, any>) {\r\n const keys = Object.keys(obj)\r\n if (!keys.length) return ''\r\n let i\r\n const len = keys.length\r\n let result = ''\r\n\r\n for (i = 0; i < len; i++) {\r\n const key = keys[i]\r\n const val = obj[key]\r\n result += hyphenate(key) + ':' + addPx(key, val) + ';'\r\n }\r\n\r\n return result\r\n}\r\n\r\n/* The following list is defined in React's core */\r\nexport const IS_UNITLESS: Record<string, boolean> = {\r\n animationIterationCount: true,\r\n boxFlex: true,\r\n boxFlexGroup: true,\r\n boxOrdinalGroup: true,\r\n columnCount: true,\r\n flex: true,\r\n flexGrow: true,\r\n flexPositive: true,\r\n flexShrink: true,\r\n flexNegative: true,\r\n flexOrder: true,\r\n gridRow: true,\r\n gridColumn: true,\r\n fontWeight: true,\r\n lineClamp: true,\r\n lineHeight: true,\r\n opacity: true,\r\n order: true,\r\n orphans: true,\r\n tabSize: true,\r\n widows: true,\r\n zIndex: true,\r\n zoom: true,\r\n\r\n // SVG-related properties\r\n fillOpacity: true,\r\n stopOpacity: true,\r\n strokeDashoffset: true,\r\n strokeOpacity: true,\r\n strokeWidth: true\r\n}\r\n\r\n/**\r\n * Will add px to the end of style values which are Numbers.\r\n * @param name\r\n * @param value\r\n * @returns {*}\r\n */\r\nexport function addPx(name: string, value: number | string) {\r\n if (typeof value === 'number' && !IS_UNITLESS[name]) {\r\n return value + 'px'\r\n } else {\r\n return value\r\n }\r\n}\r\n\r\nexport const hyphenateRE = /([a-z\\d])([A-Z])/g\r\n\r\n/**\r\n * Hyphenate a camelCase string.\r\n *\r\n * @param str\r\n * @return\r\n */\r\nexport function hyphenate(str: string) {\r\n return str.replace(hyphenateRE, '$1-$2').toLowerCase()\r\n}\r\n\r\nexport function findItemInArray(array: any[], property: string, value: any) {\r\n for (let i = 0; i < array.length; i++) {\r\n if (array[i][property] === value) {\r\n return true\r\n }\r\n }\r\n\r\n return false\r\n}\r\n\r\nexport function findAndRemove(array: any[], property: string, value: any) {\r\n array.forEach(function (result, index) {\r\n if (result[property] === value) {\r\n // Remove from array\r\n array.splice(index, 1)\r\n }\r\n })\r\n}\r\n\r\nexport function useNameHelper(block: string, namespace = 'vgl') {\r\n /**\r\n * @returns `${namespace}-${block}`\r\n */\r\n const b = () => `${namespace}-${block}`\r\n /**\r\n * @returns `${namespace}-${block}__${element}`\r\n */\r\n const be = (element: string) => `${b()}__${element}`\r\n /**\r\n * @returns `${namespace}-${block}--${modifier}`\r\n */\r\n const bm = (modifier: string | number) => `${b()}--${modifier}`\r\n /**\r\n * @returns `${namespace}-${block}__${element}--${modifier}`\r\n */\r\n const bem = (element: string, modifier: string | number) => `${b()}__${element}--${modifier}`\r\n\r\n return {\r\n b,\r\n be,\r\n bm,\r\n bem\r\n }\r\n}\r\n"],"names":["LAYOUT_KEY","EMITTER_KEY","bottom","layout","max","bottomY","i","len","cloneLayout","newLayout","cloneLayoutItem","layoutItem","collides","l1","l2","compact","verticalCompact","minPositions","compareWith","getStatics","sorted","sortLayoutItemsByRowCol","out","l","compactItem","getFirstCollision","minY","correctBounds","bounds","collidesWith","getLayoutItem","id","getAllCollisions","moveElement","x","y","isUserAction","preventCollision","oldX","oldY","movingUp","collisions","collision","moveElementAwayFromCollision","itemToMove","fakeItem","setTransform","top","left","width","height","translate","setTransformRtl","right","setTopLeft","setTopRight","a","b","validateLayout","contextName","subProps","keyArr","item","j","useNameHelper","block","namespace","element","modifier"],"mappings":"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"}