UNPKG

@wordpress/block-editor

Version:
144 lines (142 loc) 5.99 kB
export function range(start, length) { return Array.from({ length }, (_, i) => start + i); } export class GridRect { constructor({ columnStart, rowStart, columnEnd, rowEnd, columnSpan, rowSpan } = {}) { this.columnStart = columnStart !== null && columnStart !== void 0 ? columnStart : 1; this.rowStart = rowStart !== null && rowStart !== void 0 ? rowStart : 1; if (columnSpan !== undefined) { this.columnEnd = this.columnStart + columnSpan - 1; } else { this.columnEnd = columnEnd !== null && columnEnd !== void 0 ? columnEnd : this.columnStart; } if (rowSpan !== undefined) { this.rowEnd = this.rowStart + rowSpan - 1; } else { this.rowEnd = rowEnd !== null && rowEnd !== void 0 ? rowEnd : this.rowStart; } } get columnSpan() { return this.columnEnd - this.columnStart + 1; } get rowSpan() { return this.rowEnd - this.rowStart + 1; } contains(column, row) { return column >= this.columnStart && column <= this.columnEnd && row >= this.rowStart && row <= this.rowEnd; } containsRect(rect) { return this.contains(rect.columnStart, rect.rowStart) && this.contains(rect.columnEnd, rect.rowEnd); } intersectsRect(rect) { return this.columnStart <= rect.columnEnd && this.columnEnd >= rect.columnStart && this.rowStart <= rect.rowEnd && this.rowEnd >= rect.rowStart; } } export function getComputedCSS(element, property) { return element.ownerDocument.defaultView.getComputedStyle(element).getPropertyValue(property); } /** * Given a grid-template-columns or grid-template-rows CSS property value, gets the start and end * position in pixels of each grid track. * * https://css-tricks.com/snippets/css/complete-guide-grid/#aa-grid-track * * @param {string} template The grid-template-columns or grid-template-rows CSS property value. * Only supports fixed sizes in pixels. * @param {number} gap The gap between grid tracks in pixels. * * @return {Array<{start: number, end: number}>} An array of objects with the start and end * position in pixels of each grid track. */ export function getGridTracks(template, gap) { const tracks = []; for (const size of template.split(' ')) { const previousTrack = tracks[tracks.length - 1]; const start = previousTrack ? previousTrack.end + gap : 0; const end = start + parseFloat(size); tracks.push({ start, end }); } return tracks; } /** * Given an array of grid tracks and a position in pixels, gets the index of the closest track to * that position. * * https://css-tricks.com/snippets/css/complete-guide-grid/#aa-grid-track * * @param {Array<{start: number, end: number}>} tracks An array of objects with the start and end * position in pixels of each grid track. * @param {number} position The position in pixels. * @param {string} edge The edge of the track to compare the * position to. Either 'start' or 'end'. * * @return {number} The index of the closest track to the position. 0-based, unlike CSS grid which * is 1-based. */ export function getClosestTrack(tracks, position, edge = 'start') { return tracks.reduce((closest, track, index) => Math.abs(track[edge] - position) < Math.abs(tracks[closest][edge] - position) ? index : closest, 0); } export function getGridRect(gridElement, rect) { const columnGap = parseFloat(getComputedCSS(gridElement, 'column-gap')); const rowGap = parseFloat(getComputedCSS(gridElement, 'row-gap')); const gridColumnTracks = getGridTracks(getComputedCSS(gridElement, 'grid-template-columns'), columnGap); const gridRowTracks = getGridTracks(getComputedCSS(gridElement, 'grid-template-rows'), rowGap); const columnStart = getClosestTrack(gridColumnTracks, rect.left) + 1; const rowStart = getClosestTrack(gridRowTracks, rect.top) + 1; const columnEnd = getClosestTrack(gridColumnTracks, rect.right, 'end') + 1; const rowEnd = getClosestTrack(gridRowTracks, rect.bottom, 'end') + 1; return new GridRect({ columnStart, columnEnd, rowStart, rowEnd }); } export function getGridItemRect(gridItemElement) { return getGridRect(gridItemElement.parentElement, new window.DOMRect(gridItemElement.offsetLeft, gridItemElement.offsetTop, gridItemElement.offsetWidth, gridItemElement.offsetHeight)); } export function getGridInfo(gridElement) { const gridTemplateColumns = getComputedCSS(gridElement, 'grid-template-columns'); const gridTemplateRows = getComputedCSS(gridElement, 'grid-template-rows'); const borderTopWidth = getComputedCSS(gridElement, 'border-top-width'); const borderRightWidth = getComputedCSS(gridElement, 'border-right-width'); const borderBottomWidth = getComputedCSS(gridElement, 'border-bottom-width'); const borderLeftWidth = getComputedCSS(gridElement, 'border-left-width'); const paddingTop = getComputedCSS(gridElement, 'padding-top'); const paddingRight = getComputedCSS(gridElement, 'padding-right'); const paddingBottom = getComputedCSS(gridElement, 'padding-bottom'); const paddingLeft = getComputedCSS(gridElement, 'padding-left'); const numColumns = gridTemplateColumns.split(' ').length; const numRows = gridTemplateRows.split(' ').length; const numItems = numColumns * numRows; return { numColumns, numRows, numItems, currentColor: getComputedCSS(gridElement, 'color'), style: { gridTemplateColumns, gridTemplateRows, gap: getComputedCSS(gridElement, 'gap'), inset: ` calc(${paddingTop} + ${borderTopWidth}) calc(${paddingRight} + ${borderRightWidth}) calc(${paddingBottom} + ${borderBottomWidth}) calc(${paddingLeft} + ${borderLeftWidth}) ` } }; } //# sourceMappingURL=utils.js.map