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