igniteui-webcomponents
Version:
Ignite UI for Web Components is a complete library of UI components, giving you the ability to build modern web applications using encapsulation and the concept of reusable components in a dependency-free approach.
178 lines • 6.46 kB
JavaScript
import { asNumber, first } from '../common/util.js';
import { ResizeUtil } from './resize-util.js';
const CssValues = new RegExp(/(?<start>\d+)?\s*\/?\s*span\s*(?<span>\d+)?/gi);
function parseTileGridRect(tile) {
const computed = getComputedStyle(tile);
const { gridColumn, gridRow } = computed;
const [column, row] = [
first(Array.from(gridColumn.matchAll(CssValues))).groups,
first(Array.from(gridRow.matchAll(CssValues))).groups,
];
return {
column: {
start: asNumber(column.start, -1),
span: asNumber(column.span, -1),
},
row: { start: asNumber(row.start, -1), span: asNumber(row.span, -1) },
};
}
function parseTileParentGrid(gridContainer) {
const computed = getComputedStyle(gridContainer);
const { gap, gridTemplateColumns, gridTemplateRows } = computed;
const columns = gridTemplateColumns.split(' ').map(asNumber);
const rows = gridTemplateRows.split(' ').map(asNumber);
return {
gap: asNumber(gap),
columns: {
count: columns.length,
entries: columns,
minSize: asNumber(computed.getPropertyValue('--min-col-width')),
},
rows: {
count: rows.length,
entries: rows,
minSize: asNumber(computed.getPropertyValue('--min-row-height')),
},
};
}
class TileResizeState {
constructor() {
this._gap = 0;
this._prevDeltaX = 0;
this._prevDeltaY = 0;
this._prevSnappedWidth = 0;
this._prevSnappedHeight = 0;
this._position = {
column: { start: 0, span: 0 },
row: { start: 0, span: 0 },
};
this._columns = {
count: 0,
entries: [],
minSize: 0,
};
this._rows = {
count: 0,
entries: [],
minSize: 0,
};
this.resizedDimensions = {
width: null,
height: null,
};
}
get gap() {
return this._gap;
}
get position() {
return structuredClone(this._position);
}
get columns() {
return structuredClone(this._columns);
}
get rows() {
return structuredClone(this._rows);
}
calculateSnappedWidth(state) {
const resizeProps = this.getResizeProps(state);
const snappedDimension = this._resizeUtil.calculateSnappedDimension(resizeProps);
this._prevDeltaX = snappedDimension.newDelta;
this._prevSnappedWidth = snappedDimension.snappedSize;
return snappedDimension.snappedSize;
}
calculateSnappedHeight(state) {
const resizeProps = this.getResizeProps(state, true);
const snappedDimension = this._resizeUtil.calculateSnappedDimension(resizeProps);
this._prevDeltaY = snappedDimension.newDelta;
this._prevSnappedHeight = snappedDimension.snappedSize;
return snappedDimension.snappedSize;
}
updateState(tileRect, tile, grid) {
this.initState(grid, tile);
this.calculateTileStartPosition(grid, tileRect);
}
calculateResizedGridPosition(rect) {
const colProps = this.getResizeSpanProps(rect);
const rowProps = this.getResizeSpanProps(rect, true);
this._position.column.span =
this._resizeUtil.calculateResizedSpan(colProps);
this._position.row.span = this._resizeUtil.calculateResizedSpan(rowProps);
return {
colSpan: this._position.column.span,
rowSpan: this._position.row.span,
};
}
initState(grid, tile) {
const { gap, columns, rows } = parseTileParentGrid(grid);
this._resizeUtil = new ResizeUtil(gap);
this._initialPosition = parseTileGridRect(tile);
this._position = structuredClone(this._initialPosition);
this._gap = gap;
this._columns = columns;
this._rows = rows;
this._prevDeltaX = 0;
this._prevDeltaY = 0;
this._prevSnappedWidth = 0;
this._prevSnappedHeight = 0;
}
calculateTileStartPosition(grid, tileRect) {
if (this._position.column.start < 0) {
const offsetX = this.getGridOffset(grid, 'horizontal');
this._position.column.start = this._resizeUtil.calculatePosition(tileRect.left + window.scrollX + grid.scrollLeft - offsetX, this._columns.entries);
}
if (this._position.row.start < 0) {
const offsetY = this.getGridOffset(grid, 'vertical');
this._position.row.start = this._resizeUtil.calculatePosition(tileRect.top + window.scrollY - offsetY, this._rows.entries);
}
}
getGridOffset(grid, axis) {
const gridRect = grid.getBoundingClientRect();
const computed = getComputedStyle(grid);
return axis === 'horizontal'
? gridRect.left +
window.scrollX +
grid.scrollLeft +
Number.parseFloat(computed.paddingLeft)
: gridRect.top + window.scrollY + Number.parseFloat(computed.paddingTop);
}
getResizeProps(state, isRow = false) {
return isRow
? {
currentDelta: state.deltaY,
currentSize: state.current.height,
prevDelta: this._prevDeltaY,
gridEntries: this._rows.entries,
startIndex: this._position.row.start,
prevSnapped: this._prevSnappedHeight,
}
: {
currentDelta: state.deltaX,
currentSize: state.current.width,
prevDelta: this._prevDeltaX,
gridEntries: this._columns.entries,
startIndex: this._position.column.start,
prevSnapped: this._prevSnappedWidth,
};
}
getResizeSpanProps(rect, isRow = false) {
return isRow
? {
targetSize: rect.height,
tilePosition: this.position.row,
tileGridDimension: this.rows,
gap: this.gap,
isRow,
}
: {
targetSize: rect.width,
tilePosition: this.position.column,
tileGridDimension: this.columns,
gap: this.gap,
isRow,
};
}
}
export function createTileResizeState() {
return new TileResizeState();
}
//# sourceMappingURL=resize-state.js.map