react-grid-layout
Version:
A draggable and resizable grid layout with responsive breakpoints, for React.
608 lines (601 loc) • 17.4 kB
JavaScript
;
var chunkBJFPTW5Q_js = require('./chunk-BJFPTW5Q.js');
// src/core/constraints.ts
function clamp(value, min, max) {
return Math.max(min, Math.min(max, value));
}
var gridBounds = {
name: "gridBounds",
constrainPosition(item, x, y, { cols, maxRows }) {
return {
x: clamp(x, 0, Math.max(0, cols - item.w)),
y: clamp(y, 0, Math.max(0, maxRows - item.h))
};
},
constrainSize(item, w, h, handle, { cols, maxRows }) {
const maxW = handle === "w" || handle === "nw" || handle === "sw" ? item.x + item.w : cols - item.x;
const maxH = handle === "n" || handle === "nw" || handle === "ne" ? item.y + item.h : maxRows - item.y;
return {
w: clamp(w, 1, Math.max(1, maxW)),
h: clamp(h, 1, Math.max(1, maxH))
};
}
};
var minMaxSize = {
name: "minMaxSize",
constrainSize(item, w, h) {
return {
w: clamp(w, item.minW ?? 1, item.maxW ?? Infinity),
h: clamp(h, item.minH ?? 1, item.maxH ?? Infinity)
};
}
};
var containerBounds = {
name: "containerBounds",
constrainPosition(item, x, y, { cols, maxRows, containerHeight, rowHeight, margin }) {
const visibleRows = containerHeight > 0 ? Math.floor((containerHeight + margin[1]) / (rowHeight + margin[1])) : maxRows;
return {
x: clamp(x, 0, Math.max(0, cols - item.w)),
y: clamp(y, 0, Math.max(0, visibleRows - item.h))
};
}
};
var boundedX = {
name: "boundedX",
constrainPosition(item, x, y, { cols }) {
return {
x: clamp(x, 0, Math.max(0, cols - item.w)),
y
};
}
};
var boundedY = {
name: "boundedY",
constrainPosition(item, x, y, { maxRows }) {
return {
x,
y: clamp(y, 0, Math.max(0, maxRows - item.h))
};
}
};
function aspectRatio(ratio) {
return {
name: `aspectRatio(${ratio})`,
constrainSize(_item, w, _h, _handle, context) {
const { cols, containerWidth, rowHeight, margin } = context;
const colWidth = (containerWidth - margin[0] * (cols - 1)) / cols;
const pixelWidth = colWidth * w + margin[0] * Math.max(0, w - 1);
const pixelHeight = pixelWidth / ratio;
const h = Math.max(
1,
Math.round((pixelHeight + margin[1]) / (rowHeight + margin[1]))
);
return { w, h };
}
};
}
function snapToGrid(stepX, stepY = stepX) {
if (stepX <= 0 || stepY <= 0) {
throw new Error(
`snapToGrid: step values must be positive (got stepX=${stepX}, stepY=${stepY})`
);
}
return {
name: `snapToGrid(${stepX}, ${stepY})`,
constrainPosition(_item, x, y) {
return {
x: Math.round(x / stepX) * stepX,
y: Math.round(y / stepY) * stepY
};
}
};
}
function minSize(minW, minH) {
return {
name: `minSize(${minW}, ${minH})`,
constrainSize(_item, w, h) {
return {
w: Math.max(minW, w),
h: Math.max(minH, h)
};
}
};
}
function maxSize(maxW, maxH) {
return {
name: `maxSize(${maxW}, ${maxH})`,
constrainSize(_item, w, h) {
return {
w: Math.min(maxW, w),
h: Math.min(maxH, h)
};
}
};
}
var defaultConstraints = [gridBounds, minMaxSize];
function applyPositionConstraints(constraints, item, x, y, context) {
let result = { x, y };
for (const constraint of constraints) {
if (constraint.constrainPosition) {
result = constraint.constrainPosition(item, result.x, result.y, context);
}
}
if (item.constraints) {
for (const constraint of item.constraints) {
if (constraint.constrainPosition) {
result = constraint.constrainPosition(
item,
result.x,
result.y,
context
);
}
}
}
return result;
}
function applySizeConstraints(constraints, item, w, h, handle, context) {
let result = { w, h };
for (const constraint of constraints) {
if (constraint.constrainSize) {
result = constraint.constrainSize(
item,
result.w,
result.h,
handle,
context
);
}
}
if (item.constraints) {
for (const constraint of item.constraints) {
if (constraint.constrainSize) {
result = constraint.constrainSize(
item,
result.w,
result.h,
handle,
context
);
}
}
}
return result;
}
// src/core/position.ts
function setTransform({
top,
left,
width,
height
}) {
const translate = `translate(${left}px,${top}px)`;
return {
transform: translate,
WebkitTransform: translate,
MozTransform: translate,
msTransform: translate,
OTransform: translate,
width: `${width}px`,
height: `${height}px`,
position: "absolute"
};
}
function setTopLeft({
top,
left,
width,
height
}) {
return {
top: `${top}px`,
left: `${left}px`,
width: `${width}px`,
height: `${height}px`,
position: "absolute"
};
}
function perc(num) {
return num * 100 + "%";
}
function constrainWidth(left, currentWidth, newWidth, containerWidth) {
return left + newWidth > containerWidth ? currentWidth : newWidth;
}
function constrainHeight(top, currentHeight, newHeight) {
return top < 0 ? currentHeight : newHeight;
}
function constrainLeft(left) {
return Math.max(0, left);
}
function constrainTop(top) {
return Math.max(0, top);
}
var resizeNorth = (currentSize, newSize, _containerWidth) => {
const { left, height, width } = newSize;
const top = currentSize.top - (height - currentSize.height);
return {
left,
width,
height: constrainHeight(top, currentSize.height, height),
top: constrainTop(top)
};
};
var resizeEast = (currentSize, newSize, containerWidth) => {
const { top, left, height, width } = newSize;
return {
top,
height,
width: constrainWidth(
currentSize.left,
currentSize.width,
width,
containerWidth
),
left: constrainLeft(left)
};
};
var resizeWest = (currentSize, newSize, _containerWidth) => {
const { top, height, width } = newSize;
const left = currentSize.left + currentSize.width - width;
if (left < 0) {
return {
height,
width: currentSize.left + currentSize.width,
top: constrainTop(top),
left: 0
};
}
return {
height,
width,
top: constrainTop(top),
left
};
};
var resizeSouth = (currentSize, newSize, _containerWidth) => {
const { top, left, height, width } = newSize;
return {
width,
left,
height: constrainHeight(top, currentSize.height, height),
top: constrainTop(top)
};
};
var resizeNorthEast = (currentSize, newSize, containerWidth) => resizeNorth(
currentSize,
resizeEast(currentSize, newSize, containerWidth));
var resizeNorthWest = (currentSize, newSize, containerWidth) => resizeNorth(
currentSize,
resizeWest(currentSize, newSize));
var resizeSouthEast = (currentSize, newSize, containerWidth) => resizeSouth(
currentSize,
resizeEast(currentSize, newSize, containerWidth));
var resizeSouthWest = (currentSize, newSize, containerWidth) => resizeSouth(
currentSize,
resizeWest(currentSize, newSize));
var resizeHandlerMap = {
n: resizeNorth,
ne: resizeNorthEast,
e: resizeEast,
se: resizeSouthEast,
s: resizeSouth,
sw: resizeSouthWest,
w: resizeWest,
nw: resizeNorthWest
};
function resizeItemInDirection(direction, currentSize, newSize, containerWidth) {
const handler = resizeHandlerMap[direction];
if (!handler) {
return newSize;
}
return handler(currentSize, { ...currentSize, ...newSize }, containerWidth);
}
var transformStrategy = {
type: "transform",
scale: 1,
calcStyle(pos) {
return setTransform(pos);
}
};
var absoluteStrategy = {
type: "absolute",
scale: 1,
calcStyle(pos) {
return setTopLeft(pos);
}
};
function createScaledStrategy(scale) {
return {
type: "transform",
scale,
calcStyle(pos) {
return setTransform(pos);
},
calcDragPosition(clientX, clientY, offsetX, offsetY) {
return {
left: (clientX - offsetX) / scale,
top: (clientY - offsetY) / scale
};
}
};
}
var defaultPositionStrategy = transformStrategy;
// src/core/types.ts
var defaultGridConfig = {
cols: 12,
rowHeight: 150,
margin: [10, 10],
containerPadding: null,
maxRows: Infinity
};
var defaultDragConfig = {
enabled: true,
bounded: false,
threshold: 3
};
var defaultResizeConfig = {
enabled: true,
handles: ["se"]
};
var defaultDropConfig = {
enabled: false,
defaultItem: { w: 1, h: 1 }
};
// src/core/compactors.ts
function resolveCompactionCollision(layout, item, moveToCoord, axis, hasStatics) {
const sizeProp = axis === "x" ? "w" : "h";
item[axis] += 1;
const itemIndex = layout.findIndex((l) => l.i === item.i);
const layoutHasStatics = hasStatics ?? chunkBJFPTW5Q_js.getStatics(layout).length > 0;
for (let i = itemIndex + 1; i < layout.length; i++) {
const otherItem = layout[i];
if (otherItem === void 0) continue;
if (otherItem.static) continue;
if (!layoutHasStatics && otherItem.y > item.y + item.h) break;
if (chunkBJFPTW5Q_js.collides(item, otherItem)) {
resolveCompactionCollision(
layout,
otherItem,
moveToCoord + item[sizeProp],
axis,
layoutHasStatics
);
}
}
item[axis] = moveToCoord;
}
function compactItemVertical(compareWith, l, fullLayout, maxY) {
l.x = Math.max(l.x, 0);
l.y = Math.max(l.y, 0);
l.y = Math.min(maxY, l.y);
while (l.y > 0 && !chunkBJFPTW5Q_js.getFirstCollision(compareWith, l)) {
l.y--;
}
let collision;
while ((collision = chunkBJFPTW5Q_js.getFirstCollision(compareWith, l)) !== void 0) {
resolveCompactionCollision(fullLayout, l, collision.y + collision.h, "y");
}
l.y = Math.max(l.y, 0);
return l;
}
function compactItemHorizontal(compareWith, l, cols, fullLayout) {
l.x = Math.max(l.x, 0);
l.y = Math.max(l.y, 0);
while (l.x > 0 && !chunkBJFPTW5Q_js.getFirstCollision(compareWith, l)) {
l.x--;
}
let collision;
while ((collision = chunkBJFPTW5Q_js.getFirstCollision(compareWith, l)) !== void 0) {
resolveCompactionCollision(fullLayout, l, collision.x + collision.w, "x");
if (l.x + l.w > cols) {
l.x = cols - l.w;
l.y++;
while (l.x > 0 && !chunkBJFPTW5Q_js.getFirstCollision(compareWith, l)) {
l.x--;
}
}
}
l.x = Math.max(l.x, 0);
return l;
}
var verticalCompactor = {
type: "vertical",
allowOverlap: false,
compact(layout, _cols) {
const compareWith = chunkBJFPTW5Q_js.getStatics(layout);
let maxY = chunkBJFPTW5Q_js.bottom(compareWith);
const sorted = chunkBJFPTW5Q_js.sortLayoutItemsByRowCol(layout);
const out = new Array(layout.length);
for (let i = 0; i < sorted.length; i++) {
const sortedItem = sorted[i];
if (sortedItem === void 0) continue;
let l = chunkBJFPTW5Q_js.cloneLayoutItem(sortedItem);
if (!l.static) {
l = compactItemVertical(compareWith, l, sorted, maxY);
maxY = Math.max(maxY, l.y + l.h);
compareWith.push(l);
}
const originalIndex = layout.indexOf(sortedItem);
out[originalIndex] = l;
l.moved = false;
}
return out;
}
};
var horizontalCompactor = {
type: "horizontal",
allowOverlap: false,
compact(layout, cols) {
const compareWith = chunkBJFPTW5Q_js.getStatics(layout);
const sorted = chunkBJFPTW5Q_js.sortLayoutItemsByColRow(layout);
const out = new Array(layout.length);
for (let i = 0; i < sorted.length; i++) {
const sortedItem = sorted[i];
if (sortedItem === void 0) continue;
let l = chunkBJFPTW5Q_js.cloneLayoutItem(sortedItem);
if (!l.static) {
l = compactItemHorizontal(compareWith, l, cols, sorted);
compareWith.push(l);
}
const originalIndex = layout.indexOf(sortedItem);
out[originalIndex] = l;
l.moved = false;
}
return out;
}
};
var noCompactor = {
type: null,
allowOverlap: false,
compact(layout, _cols) {
return chunkBJFPTW5Q_js.cloneLayout(layout);
}
};
var verticalOverlapCompactor = {
...verticalCompactor,
allowOverlap: true,
compact(layout, _cols) {
return chunkBJFPTW5Q_js.cloneLayout(layout);
}
};
var horizontalOverlapCompactor = {
...horizontalCompactor,
allowOverlap: true,
compact(layout, _cols) {
return chunkBJFPTW5Q_js.cloneLayout(layout);
}
};
var noOverlapCompactor = {
...noCompactor,
allowOverlap: true
};
function getCompactor(compactType, allowOverlap = false, preventCollision = false) {
let baseCompactor;
if (allowOverlap) {
if (compactType === "vertical") baseCompactor = verticalOverlapCompactor;
else if (compactType === "horizontal")
baseCompactor = horizontalOverlapCompactor;
else baseCompactor = noOverlapCompactor;
} else {
if (compactType === "vertical") baseCompactor = verticalCompactor;
else if (compactType === "horizontal") baseCompactor = horizontalCompactor;
else baseCompactor = noCompactor;
}
if (preventCollision) {
return { ...baseCompactor, preventCollision };
}
return baseCompactor;
}
// src/core/responsive.ts
function sortBreakpoints(breakpoints) {
const keys = Object.keys(breakpoints);
return keys.sort((a, b) => breakpoints[a] - breakpoints[b]);
}
function getBreakpointFromWidth(breakpoints, width) {
const sorted = sortBreakpoints(breakpoints);
let matching = sorted[0];
if (matching === void 0) {
throw new Error("No breakpoints defined");
}
for (let i = 1; i < sorted.length; i++) {
const breakpointName = sorted[i];
if (breakpointName === void 0) continue;
const breakpointWidth = breakpoints[breakpointName];
if (width > breakpointWidth) {
matching = breakpointName;
}
}
return matching;
}
function getColsFromBreakpoint(breakpoint, cols) {
const colCount = cols[breakpoint];
if (colCount === void 0) {
throw new Error(
`ResponsiveReactGridLayout: \`cols\` entry for breakpoint ${String(breakpoint)} is missing!`
);
}
return colCount;
}
function findOrGenerateResponsiveLayout(layouts, breakpoints, breakpoint, lastBreakpoint, cols, compactTypeOrCompactor) {
const existingLayout = layouts[breakpoint];
if (existingLayout) {
return chunkBJFPTW5Q_js.cloneLayout(existingLayout);
}
let layout = layouts[lastBreakpoint];
const breakpointsSorted = sortBreakpoints(breakpoints);
const breakpointsAbove = breakpointsSorted.slice(
breakpointsSorted.indexOf(breakpoint)
);
for (let i = 0; i < breakpointsAbove.length; i++) {
const b = breakpointsAbove[i];
if (b === void 0) continue;
const layoutForBreakpoint = layouts[b];
if (layoutForBreakpoint) {
layout = layoutForBreakpoint;
break;
}
}
const clonedLayout = chunkBJFPTW5Q_js.cloneLayout(layout || []);
const corrected = chunkBJFPTW5Q_js.correctBounds(clonedLayout, { cols });
const compactor = typeof compactTypeOrCompactor === "object" && compactTypeOrCompactor !== null ? compactTypeOrCompactor : getCompactor(compactTypeOrCompactor);
return compactor.compact(corrected, cols);
}
function getIndentationValue(value, breakpoint) {
if (Array.isArray(value)) {
return value;
}
const breakpointMap = value;
const breakpointValue = breakpointMap[breakpoint];
if (breakpointValue !== void 0) {
return breakpointValue;
}
const keys = Object.keys(breakpointMap);
for (const key of keys) {
const v = breakpointMap[key];
if (v !== void 0) {
return v;
}
}
return [10, 10];
}
exports.absoluteStrategy = absoluteStrategy;
exports.applyPositionConstraints = applyPositionConstraints;
exports.applySizeConstraints = applySizeConstraints;
exports.aspectRatio = aspectRatio;
exports.boundedX = boundedX;
exports.boundedY = boundedY;
exports.compactItemHorizontal = compactItemHorizontal;
exports.compactItemVertical = compactItemVertical;
exports.containerBounds = containerBounds;
exports.createScaledStrategy = createScaledStrategy;
exports.defaultConstraints = defaultConstraints;
exports.defaultDragConfig = defaultDragConfig;
exports.defaultDropConfig = defaultDropConfig;
exports.defaultGridConfig = defaultGridConfig;
exports.defaultPositionStrategy = defaultPositionStrategy;
exports.defaultResizeConfig = defaultResizeConfig;
exports.findOrGenerateResponsiveLayout = findOrGenerateResponsiveLayout;
exports.getBreakpointFromWidth = getBreakpointFromWidth;
exports.getColsFromBreakpoint = getColsFromBreakpoint;
exports.getCompactor = getCompactor;
exports.getIndentationValue = getIndentationValue;
exports.gridBounds = gridBounds;
exports.horizontalCompactor = horizontalCompactor;
exports.horizontalOverlapCompactor = horizontalOverlapCompactor;
exports.maxSize = maxSize;
exports.minMaxSize = minMaxSize;
exports.minSize = minSize;
exports.noCompactor = noCompactor;
exports.noOverlapCompactor = noOverlapCompactor;
exports.perc = perc;
exports.resizeItemInDirection = resizeItemInDirection;
exports.resolveCompactionCollision = resolveCompactionCollision;
exports.setTopLeft = setTopLeft;
exports.setTransform = setTransform;
exports.snapToGrid = snapToGrid;
exports.sortBreakpoints = sortBreakpoints;
exports.transformStrategy = transformStrategy;
exports.verticalCompactor = verticalCompactor;
exports.verticalOverlapCompactor = verticalOverlapCompactor;
//# sourceMappingURL=chunk-2DDROKB2.js.map
//# sourceMappingURL=chunk-2DDROKB2.js.map