appbir-layout
Version:
layout you PC web applation
701 lines (611 loc) • 27 kB
JavaScript
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory(require("react"));
else if(typeof define === 'function' && define.amd)
define(["react"], factory);
else if(typeof exports === 'object')
exports["app-layout"] = factory(require("react"));
else
root["app-layout"] = factory(root["react"]);
})(typeof self !== 'undefined' ? self : this, function(__WEBPACK_EXTERNAL_MODULE_5__) {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
module.exports = __webpack_require__(1);
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.arrayToTree = exports.PARTS = exports.POSITION = undefined;
var _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; }; /**
* 该布局适合整站布局
* ---------------------
* 如果想局部布局,则可以使用auto 或者diy模式 (TODO 该两种模式还未完全成熟)
*
* 局部布局需要使用style传递对应的miniheight 最小高度 或者使用样式覆盖
*
* 有必要场景可扩展排序规则
*/
var _propTypes = __webpack_require__(2);
var _propTypes2 = _interopRequireDefault(_propTypes);
var _react = __webpack_require__(5);
var _react2 = _interopRequireDefault(_react);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* FULL: full layout include priority
* AUTO: 100% 按照外层百分比进行
* DIY : define you width or height
*/
var POSITION = exports.POSITION = { FULL: 'FULL', AUTO: 'AUTO', 'DIY': 'DIY' };
var PARTS = exports.PARTS = {
// 最外层容器 最大容器
MAIN_CONTAINER: 'main_container',
// 辅助左右布局容器
LEFT_RIGHT_CONTAINER: 'left_right_container',
// 过度容器
LEFT_CONTAINER: 'left_container',
RIGHT_CONTAINER: 'right_container',
BOTTOM_CONTAINER: 'bottom_container',
// 内容区域容器
CONTENT_CONTAINER: 'content-container',
// 组成部分
HEADER: 'header',
LEFT: 'left',
RIGHT: 'right',
BOTTOM: 'bottom',
CONTENT: 'content',
CONTENT_HEADER: 'content_header'
// 元素节点排序
};var ORDER = [PARTS.CONTENT, PARTS.HEADER, PARTS.LEFT, PARTS.RIGHT, PARTS.BOTTOM, PARTS.CONTENT_HEADER];
var getChildren = function getChildren(current, opt, array) {
var id = current[opt.keyFiled];
var childEle = [];
array.map(function (item) {
if (item[opt.parentFiled] === id) {
childEle.push(item);
}
});
childEle.length && childEle.map(function (ele) {
ele[opt.childFiled] = getChildren(ele, opt, array);
});
return childEle;
};
var arrayToTree = exports.arrayToTree = function arrayToTree(array, option) {
if (!array || !array.length) return option && option.returnType === 'object' ? {} : [];
var opt = { parentFiled: 'parent', keyFiled: 'id', childFiled: 'children', returnType: 'tree' };
typeof option === 'string' ? opt.parentFiled = option : opt = _extends({}, opt, option);
var temp = {},
first = [];
array.map(function (obj) {
return temp[obj[opt.keyFiled]] = obj;
});
array.map(function (current) {
var parent = current[opt.parentFiled];
if (!parent || !temp[parent]) {
first.push(current);
}
});
first && first.map(function (firstChild) {
firstChild[opt.childFiled] = getChildren(firstChild, opt, array);
});
return opt.returnType === 'object' ? temp : first;
};
// 是否合法的参数
var isLegal = function isLegal(size) {
return size && !POSITION[size] && /px/.test(size);
};
// 像素计算
var add = function add(first, second) {
return isLegal(second) ? parseInt((first || '0').split('px')[0]) + parseInt((second || '0').split('px')[0]) + 'px' : first;
};
// 是否整合
var isIntegrate = function isIntegrate(size, isWidth) {
return isWidth ? [PARTS.LEFT, PARTS.RIGHT].indexOf(size) != -1 : [PARTS.HEADER, PARTS.BOTTOM].indexOf(size) != -1;
};
// 计算宽度或高度
var integrate = function integrate(integration, part, name) {
isIntegrate(name) && (integration.height = add(integration.height, part.height));
isIntegrate(name, true) && (integration.width = add(integration.width, part.width));
};
// 是否满屏
var isFull = function isFull(name, config, isHeight) {
return (config[name] || false) && (isHeight ? config[name].height === POSITION.FULL : config[name].width === POSITION.FULL);
};
var Layout = function Layout(_ref) {
var _ref$classNamePrefix = _ref.classNamePrefix,
classNamePrefix = _ref$classNamePrefix === undefined ? 'appbir-layout-' : _ref$classNamePrefix,
_ref$targetName = _ref.targetName,
targetName = _ref$targetName === undefined ? 'targetName' : _ref$targetName,
_ref$config = _ref.config,
config = _ref$config === undefined ? {} : _ref$config,
children = _ref.children,
_ref$style = _ref.style,
style = _ref$style === undefined ? {} : _ref$style,
_ref$model = _ref.model,
model = _ref$model === undefined ? POSITION.FULL : _ref$model;
// 是否为全屏模式
var isFullModel = model === POSITION.FULL;
var cfg = {};
for (var name in config) {
var partCfg = config[name];
partCfg.visiabled && (cfg[name] = partCfg);
}
/**
* 根据模型 返回固定位置类型
*/
var getFixedPosition = function getFixedPosition() {
return model !== POSITION.FULL ? 'absolute' : 'fixed';
};
// 计算样式
var calcStyle = function calcStyle(config) {
var styles = [];
// 记录宽度和高度
var integration = {
width: '',
height: ''
// 是否为纵向布局
};var mainIsRow = !isFull(PARTS.HEADER, cfg) ? isFull(PARTS.LEFT, cfg, true) + isFull(PARTS.RIGHT, cfg, true) ? true : false : false;
// ------------------------------main conrainer--------------------------------------
var mainStyle = _extends({
// 1: tips 如果指定宽度 则flex 在overflow后会出现横向的滚动条
// 2: tips 如果指定高度 则超出宽度不会被布局
minHeight: '100vh',
display: 'flex',
width: '100%',
height: '100%',
flexDirection: mainIsRow ? 'row' : 'column',
position: model == POSITION.FULL ? 'static' : 'relative'
}, style);
// 非全屏模式不设置制动
if (!isFullModel) {
mainStyle.minHeight = '0px';
}
styles.push({ name: PARTS.MAIN_CONTAINER, style: mainStyle, parent: null });
// 指针节点
var parentNode = PARTS.MAIN_CONTAINER;
// ------------------------------left_right conrainer--------------------------------------
var mainNode = PARTS.MAIN_CONTAINER;
var rightNode = '';
var leftNode = '';
var isLeft = false;
var isTop = false;
var isRight = cfg[PARTS.RIGHT] && cfg[PARTS.RIGHT].fixed && cfg[PARTS.RIGHT].width;
var headerConfig = cfg[PARTS.HEADER];
var rightConfig = cfg[PARTS.RIGHT];
var leftConfig = cfg[PARTS.LEFT];
if (mainIsRow) {
parentNode = PARTS.LEFT_RIGHT_CONTAINER;
var leftRightContainerStyle = {
flex: 1,
display: 'flex',
position: 'relative',
flexDirection: 'column'
};
if (leftConfig && leftConfig.fixed && leftConfig.width) {
if (leftConfig.height != POSITION.FULL && rightConfig && rightConfig.height === POSITION.FULL) {} else {
leftRightContainerStyle.marginLeft = leftConfig.width;
isLeft = true;
}
}
styles.push({ name: PARTS.LEFT_RIGHT_CONTAINER, parent: PARTS.MAIN_CONTAINER, style: leftRightContainerStyle });
}
var bottomNode = parentNode;
// ------------------------------header--------------------------------------
if (headerConfig) {
var headerStyle = {
flex: '0 0 ' + headerConfig.height,
order: -1
};
if (headerConfig.fixed) {
headerStyle = {
position: getFixedPosition(),
width: '100%',
zIndex: headerConfig.zIndex,
height: headerConfig.height
};
integrate(integration, headerConfig, PARTS.HEADER);
}
styles.push({ name: PARTS.HEADER, parent: parentNode, style: headerStyle });
}
// ------------------------------left or right conrainer--------------------------------------
if (cfg[PARTS.LEFT] || cfg[PARTS.RIGHT]) {
if (mainIsRow && isFull(PARTS.LEFT, cfg, true) && isFull(PARTS.RIGHT, cfg, true)) {
rightNode = mainNode;
leftNode = mainNode;
} else {
var containerStyle = {
flex: 1,
display: 'flex',
flexDirection: 'row',
position: 'relative'
};
if (integration.height) {
containerStyle.marginTop = integration.height;
isTop = true;
}
styles.push({ name: PARTS.LEFT_CONTAINER, parent: parentNode, style: containerStyle });
rightNode = mainIsRow && isFull(PARTS.RIGHT, cfg, true) ? mainNode : PARTS.LEFT_CONTAINER;
leftNode = mainIsRow && isFull(PARTS.LEFT, cfg, true) ? mainNode : PARTS.LEFT_CONTAINER;
parentNode = PARTS.LEFT_CONTAINER;
}
}
// ------------------------------left--------------------------------------
if (leftConfig) {
var leftStyle = {
flex: ' 0 0 ' + leftConfig.width,
order: -1
};
if (leftConfig.fixed) {
leftStyle = {
position: getFixedPosition(),
width: leftConfig.width,
height: '100%',
zIndex: leftConfig.zIndex
};
integrate(integration, leftConfig, PARTS.LEFT);
}
if (isFull(PARTS.LEFT, cfg, true) + isFull(PARTS.RIGHT, cfg, true) === 1 && cfg[PARTS.BOTTOM] && cfg[PARTS.RIGHT] && cfg[PARTS.LEFT]) {
if (!isFull(PARTS.LEFT, cfg, true)) {
if (isFull(PARTS.HEADER, cfg)) {
leftNode = PARTS.BOTTOM_CONTAINER;
}
}
}
var lNode = leftNode || (mainIsRow && isFull(PARTS.LEFT, cfg, true) ? PARTS.MAIN_CONTAINER : parentNode);
styles.push({ name: PARTS.LEFT, parent: lNode, style: leftStyle });
}
// ------------------------------right conrainer--------------------------------------
if (isFull(PARTS.LEFT, cfg, true) + isFull(PARTS.RIGHT, cfg, true) === 1 && cfg[PARTS.BOTTOM] && cfg[PARTS.RIGHT] && cfg[PARTS.LEFT]) {
var rightContainerStyle = {
flex: 1,
display: 'flex',
flexDirection: 'column'
};
if (!mainIsRow && integration.width) {
rightContainerStyle.marginLeft = integration.width;
isLeft = true;
}
styles.push({ name: PARTS.RIGHT_CONTAINER, parent: parentNode, style: rightContainerStyle });
parentNode = PARTS.RIGHT_CONTAINER;
}
// ------------------------------bottom conrainer--------------------------------------
if (isFull(PARTS.HEADER, cfg) && isFull(PARTS.LEFT, cfg, true) + isFull(PARTS.RIGHT, cfg, true) === 1 && cfg[PARTS.BOTTOM] && cfg[PARTS.RIGHT]) {
var bContainerStyle = {
display: 'flex',
flexDirection: 'row',
flex: '1'
};
styles.push({ name: PARTS.BOTTOM_CONTAINER, parent: parentNode, style: bContainerStyle });
if (!isFull(PARTS.RIGHT, cfg, true)) {
rightNode = PARTS.BOTTOM_CONTAINER;
}
bottomNode = parentNode;
parentNode = PARTS.BOTTOM_CONTAINER;
}
var contentNode = parentNode;
// ------------------------------content and content container--------------------------------------
var isContentHeader = false;
var content_headerConfig = cfg[PARTS.CONTENT_HEADER];
if (content_headerConfig) {
contentNode = PARTS.CONTENT_CONTAINER;
var cContainerStyle = {
display: 'flex',
flexDirection: 'column',
flex: '1 1',
position: 'relative'
};
if (!isLeft && integration.width) {
cContainerStyle.marginLeft = integration.width;
isLeft = true;
}
if (!isTop && integration.height) {
cContainerStyle.marginTop = integration.height;
isTop = true;
}
if (isFull(PARTS.LEFT, cfg, true)) {
if (isFull(PARTS.RIGHT, cfg, true) || !cfg[PARTS.RIGHT]) {
bottomNode = contentNode;
}
}
if (isRight) {
cContainerStyle.marginRight = isRight;
isRight = false;
}
styles.push({ name: PARTS.CONTENT_CONTAINER, parent: parentNode, style: cContainerStyle });
var content_headerStyle = {
flex: '0 0 ' + content_headerConfig.height
};
if (content_headerConfig.fixed) {
// let calcWidth = add(leftConfig && leftConfig.width,rightConfig && rightConfig.width) || '0px';
content_headerStyle = {
// width:'calc(100vw - '+ calcWidth +')',
width: '100%',
height: content_headerConfig.height,
position: getFixedPosition(),
zIndex: content_headerConfig.zIndex
};
isContentHeader = content_headerConfig.height;
}
styles.push({ name: PARTS.CONTENT_HEADER, parent: contentNode, style: content_headerStyle });
}
// ------------------------------content--------------------------------------
var contentConfig = cfg[PARTS.CONTENT];
if (contentConfig) {
var contentStyle = { flex: 1 };
if (!isLeft && integration.width) {
contentStyle.marginLeft = integration.width;
}
if (isContentHeader) {
contentStyle.marginTop = isContentHeader;
}
if (!isTop && integration.height) {
contentStyle.marginTop = integration.height;
}
if (isRight) {
contentStyle.marginRight = isRight;
isRight = false;
}
styles.push({ name: PARTS.CONTENT, parent: contentNode, style: contentStyle });
}
// ------------------------------right--------------------------------------
if (rightConfig) {
var rightStyle = {
flex: ' 0 0 ' + rightConfig.width,
order: 1
};
if (rightConfig.fixed) {
rightStyle = {
position: getFixedPosition(),
width: rightConfig.width,
zIndex: rightConfig.zIndex,
height: '100%',
right: 0
};
if (content_headerConfig && content_headerConfig.fixed) {
if (content_headerConfig.width === POSITION.FULL && rightConfig.height != POSITION.FULL) {
rightStyle.marginTop = content_headerConfig.height;
}
}
}
var rNode = rightNode || parentNode;
styles.push({ name: PARTS.RIGHT, parent: rNode, style: rightStyle });
}
// ------------------------------bottom--------------------------------------
var bottomConfig = cfg[PARTS.BOTTOM];
if (bottomConfig) {
var bottomStyle = {
flex: ' 0 0 ' + bottomConfig.height,
order: 1
};
if (bottomConfig.fixed) {
bottomStyle = {
position: getFixedPosition(),
width: '100%',
zIndex: bottomConfig.zIndex,
height: bottomConfig.height,
bottom: 0
};
}
if (bottomNode === mainNode && integration.width) {
if (!isFull(PARTS.BOTTOM, cfg) && isFullModel) {
// 非全屏情况
bottomStyle.marginLeft = integration.width;
}
}
styles.push({ name: PARTS.BOTTOM, parent: bottomNode, style: bottomStyle });
}
return arrayToTree(styles, { keyFiled: 'name' });
};
// 转换子节点到树
var childrenToTree = function childrenToTree(children, name) {
var tree = {};
if (!children) return tree;
if (!Array.isArray(children)) {
// 兼容react单个子元素是对象
children = [children];
}
children.map(function (child, index) {
var tName = child.props[name] || ORDER[index];
tree[tName] = child;
});
return tree;
};
var createPart = function createPart(config, child, childrenMap) {
return _react2.default.createElement(
'div',
{ key: config.name,
style: config.style,
className: classNamePrefix + config.name },
child || childrenMap[config.name]
);
};
var createDom = function createDom(styleTree, childrenMap, cfg) {
if (!styleTree || !styleTree.length) return null;
var dom = [];
styleTree.map(function (config) {
var child = config.children && config.children.length && createDom(config.children, childrenMap, cfg);
var partDom = createPart(config, child, childrenMap);
dom.push(partDom);
});
return dom;
};
var childrenMap = childrenToTree(children, targetName);
var styleTree = calcStyle(cfg);
return createDom(styleTree, childrenMap, cfg);
};
Layout.propTypes = {
classNamePrefix: _propTypes2.default.string, // 样式前缀 避免样式冲突
targetName: _propTypes2.default.string, // 指定组件属于那部分 PARTS 对应的部分
config: _propTypes2.default.object, // 各模块的布局配置
model: _propTypes2.default.string, // POSITION 的三种状态 FULL 、AUTO 、DIY 默认FULL
style: _propTypes2.default.object // DIY 模式下的样式 控制layout的主体部分
};
exports.default = Layout;
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
if (false) {
var ReactIs = require('react-is');
// By explicitly using `prop-types` you are opting into new development behavior.
// http://fb.me/prop-types-in-prod
var throwOnDirectAccess = true;
module.exports = require('./factoryWithTypeCheckers')(ReactIs.isElement, throwOnDirectAccess);
} else {
// By explicitly using `prop-types` you are opting into new production behavior.
// http://fb.me/prop-types-in-prod
module.exports = __webpack_require__(3)();
}
/***/ }),
/* 3 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var ReactPropTypesSecret = __webpack_require__(4);
function emptyFunction() {}
function emptyFunctionWithReset() {}
emptyFunctionWithReset.resetWarningCache = emptyFunction;
module.exports = function() {
function shim(props, propName, componentName, location, propFullName, secret) {
if (secret === ReactPropTypesSecret) {
// It is still safe when called from React.
return;
}
var err = new Error(
'Calling PropTypes validators directly is not supported by the `prop-types` package. ' +
'Use PropTypes.checkPropTypes() to call them. ' +
'Read more at http://fb.me/use-check-prop-types'
);
err.name = 'Invariant Violation';
throw err;
};
shim.isRequired = shim;
function getShim() {
return shim;
};
// Important!
// Keep this list in sync with production version in `./factoryWithTypeCheckers.js`.
var ReactPropTypes = {
array: shim,
bool: shim,
func: shim,
number: shim,
object: shim,
string: shim,
symbol: shim,
any: shim,
arrayOf: getShim,
element: shim,
elementType: shim,
instanceOf: getShim,
node: shim,
objectOf: getShim,
oneOf: getShim,
oneOfType: getShim,
shape: getShim,
exact: getShim,
checkPropTypes: emptyFunctionWithReset,
resetWarningCache: emptyFunction
};
ReactPropTypes.PropTypes = ReactPropTypes;
return ReactPropTypes;
};
/***/ }),
/* 4 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
module.exports = ReactPropTypesSecret;
/***/ }),
/* 5 */
/***/ (function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE_5__;
/***/ })
/******/ ]);
});
//# sourceMappingURL=app-layout.js.map