UNPKG

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
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