react-grata
Version:
Light weight react grid layout component that supports IE 11. What you draw is what you get.
349 lines (294 loc) • 9.88 kB
JavaScript
import React, { useLayoutEffect } from 'react';
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
function _extends() {
_extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends.apply(this, arguments);
}
function _objectWithoutPropertiesLoose(source, excluded) {
if (source == null) return {};
var target = {};
var sourceKeys = Object.keys(source);
var key, i;
for (i = 0; i < sourceKeys.length; i++) {
key = sourceKeys[i];
if (excluded.indexOf(key) >= 0) continue;
target[key] = source[key];
}
return target;
}
var connect = function connect(arr) {
return arr.join(' ');
};
var deriveMsDimension = function deriveMsDimension(dimension, gap) {
var result = [];
var arrayIndex = 0;
var count = 0;
while (count < 2 * dimension.length - 1) {
if (count++ % 2 === 0) {
result.push(dimension[arrayIndex++]);
} else {
result.push(gap.toString());
}
}
return connect(result);
};
var deriveAutoDimensions = function deriveAutoDimensions(children) {
var maxColumns = 0;
var maxRows = 0;
if (children) {
React.Children.forEach(children, function (child) {
var _child$props = child.props,
_child$props$row = _child$props.row,
row = _child$props$row === void 0 ? 1 : _child$props$row,
_child$props$column = _child$props.column,
column = _child$props$column === void 0 ? 1 : _child$props$column,
_child$props$rowSpan = _child$props.rowSpan,
rowSpan = _child$props$rowSpan === void 0 ? 1 : _child$props$rowSpan,
_child$props$columnSp = _child$props.columnSpan,
columnSpan = _child$props$columnSp === void 0 ? 1 : _child$props$columnSp;
if (row + rowSpan - 1 > maxRows) {
maxRows = row + rowSpan - 1;
}
if (column + columnSpan - 1 > maxColumns) {
maxColumns = column + columnSpan - 1;
}
});
}
return {
columns: Array(maxColumns).fill('1fr'),
rows: Array(maxRows).fill('1fr')
};
};
var arrayToObject = function arrayToObject(arr, key) {
var obj = {};
arr.forEach(function (x) {
return obj[x[key]] = x;
});
return obj;
};
var assignCellLayout = function assignCellLayout(children, layout) {
var layoutById = arrayToObject(layout, 'id');
return React.Children.map(children, function (child) {
return React.cloneElement(child, _extends(_extends({}, layoutById[child.props.id]), child.props));
});
};
var deriveLayout = function deriveLayout(matrix) {
var layout = {};
matrix.forEach(function (row, i) {
row.forEach(function (cell, j) {
if (layout[cell]) {
if (layout[cell].row === i + 1) {
layout[cell].columnSpan++;
} else if (layout[cell].column === j + 1) {
layout[cell].rowSpan++;
}
} else if (cell) {
layout[cell] = {
id: cell,
row: i + 1,
column: j + 1,
rowSpan: 1,
columnSpan: 1
};
}
});
});
return Object.keys(layout).map(function (id) {
return layout[id];
});
};
var CustomCss;
(function (CustomCss) {
CustomCss["FitHeight"] = "fit-height";
})(CustomCss || (CustomCss = {}));
var replaceCustomGridTemplate = function replaceCustomGridTemplate(gridReplacement) {
return replaceCustomRows(gridReplacement);
};
var replaceCustomRows = function replaceCustomRows(_ref) {
var rows = _ref.rows,
rowGap = _ref.rowGap,
rest = _objectWithoutPropertiesLoose(_ref, ["rows", "rowGap"]);
var gaps = Array(rows.length - 1).fill(rowGap).join(' - ');
var otherRows = '0';
if (rows.includes(CustomCss.FitHeight)) {
otherRows = rows.filter(function (x) {
return x !== CustomCss.FitHeight;
}).join(' - ');
}
var newRows = rows.map(function (size) {
if (size === CustomCss.FitHeight) {
return "calc(100% - " + otherRows + " - " + gaps + ")";
}
return size;
});
return _extends({
rows: newRows,
rowGap: rowGap
}, rest);
};
var StyleSheetProvider = /*#__PURE__*/function () {
function StyleSheetProvider() {
var style = document.createElement('style');
style.setAttribute('data-grata', '');
document.head.appendChild(style);
this.sheet = style.sheet;
}
_createClass(StyleSheetProvider, [{
key: "styleSheet",
get: function get() {
return this.sheet;
}
}], [{
key: "instance",
get: function get() {
if (!StyleSheetProvider.INSTANCE) {
StyleSheetProvider.INSTANCE = new StyleSheetProvider();
}
return StyleSheetProvider.INSTANCE;
}
}]);
return StyleSheetProvider;
}();
var insertRules = function insertRules(rules) {
var sheet = StyleSheetProvider.instance.styleSheet;
if (!sheet) {
throw new Error('Failed to find CSSStyleSheet from the style element');
}
sheet.insertRule(rules, sheet.cssRules.length);
};
var AD_REPLACER_R = /(a)(d)/gi;
var charsLength = 52;
var getAlphabeticChar = function getAlphabeticChar(code) {
return String.fromCharCode(code + (code > 25 ? 39 : 97));
};
function generateAlphabeticName(code) {
var name = '';
var x;
for (x = Math.abs(code); x > charsLength; x = x / charsLength | 0) {
name = getAlphabeticChar(x % charsLength) + name;
}
return (getAlphabeticChar(x % charsLength) + name).replace(AD_REPLACER_R, '$1-$2');
}
var SEED = 5381;
var phash = function phash(h, x) {
var i = x.length;
while (i) {
h = h * 33 ^ x.charCodeAt(--i);
}
return h;
};
var hash = function hash(x) {
return phash(SEED, x);
};
var generateComponentId = (function (str) {
return generateAlphabeticName(hash(str) >>> 0);
});
var ClassName;
(function (ClassName) {
ClassName["GRID"] = "grata-grid";
ClassName["CELL"] = "grata-cell";
})(ClassName || (ClassName = {}));
var GridBase = function GridBase(props) {
var rows = props.rows,
columns = props.columns,
rest = _objectWithoutPropertiesLoose(props, ["rows", "columns"]);
var _rest$rowGap = rest.rowGap,
rowGap = _rest$rowGap === void 0 ? 0 : _rest$rowGap,
_rest$columnGap = rest.columnGap,
columnGap = _rest$columnGap === void 0 ? 0 : _rest$columnGap,
children = rest.children,
className = rest.className;
var autoDimensions = deriveAutoDimensions(children);
if (!rows) {
rows = autoDimensions.rows;
}
if (!columns) {
columns = autoDimensions.columns;
}
var newGridTemplate = replaceCustomGridTemplate({
rows: rows,
columns: columns,
rowGap: rowGap,
columnGap: columnGap
});
rows = newGridTemplate.rows;
columns = newGridTemplate.columns;
var msRows = deriveMsDimension(rows, rowGap);
var msColumns = deriveMsDimension(columns, columnGap);
var dynamicRules = "\n grid-row-gap: " + rowGap + ";\n grid-column-gap: " + columnGap + ";\n grid-template-rows: " + connect(rows) + ";\n grid-template-columns: " + connect(columns) + ";\n\n -ms-grid-rows: " + msRows + ";\n -ms-grid-columns: " + msColumns + ";\n ";
var gridClass = generateComponentId(dynamicRules);
var rules = "\n ." + gridClass + " {\n display: grid;\n display: -ms-grid;\n " + dynamicRules + "\n }\n ";
var mergedClassName = gridClass + " " + (className || ClassName.GRID);
useLayoutEffect(function () {
insertRules(rules);
});
return React.createElement("div", {
className: mergedClassName
}, children);
};
var Grid = function Grid(props) {
var layout = props.layout;
var children = props.children,
matrix = props.matrix,
rest = _objectWithoutPropertiesLoose(props, ["children", "matrix"]);
var cells = children;
if (matrix) {
layout = deriveLayout(matrix);
}
if (layout) {
cells = assignCellLayout(children, layout);
}
return React.createElement(GridBase, _extends({}, rest), cells);
};
var Cell = function Cell(props) {
var row = props.row,
_props$rowSpan = props.rowSpan,
rowSpan = _props$rowSpan === void 0 ? 1 : _props$rowSpan,
column = props.column,
_props$columnSpan = props.columnSpan,
columnSpan = _props$columnSpan === void 0 ? 1 : _props$columnSpan,
children = props.children,
className = props.className;
if (!row || !column) {
return null;
}
var msRow = 2 * row - 1;
var msRowSpan = 2 * rowSpan - 1;
var msColumn = 2 * column - 1;
var msColumnSpan = 2 * columnSpan - 1;
var dynamicRules = "\n grid-row: " + row + " / span " + rowSpan + ";\n grid-column: " + column + " / span " + columnSpan + ";\n\n -ms-grid-row: " + msRow + ";\n -ms-grid-row-span: " + msRowSpan + ";\n -ms-grid-column: " + msColumn + ";\n -ms-grid-column-span: " + msColumnSpan + ";\n ";
var cellClass = generateComponentId(dynamicRules);
var rules = "\n ." + cellClass + " {\n " + dynamicRules + "\n }";
var mergedClassName = cellClass + " " + (className || ClassName.CELL);
useLayoutEffect(function () {
insertRules(rules);
});
return React.createElement("div", {
className: mergedClassName
}, children);
};
export { Cell, ClassName, Grid };
//# sourceMappingURL=index.modern.js.map