@alifd/next
Version:
A configurable component library for web built on React.
692 lines (549 loc) • 27.1 kB
JavaScript
'use strict';
exports.__esModule = true;
var _objectWithoutProperties2 = require('babel-runtime/helpers/objectWithoutProperties');
var _objectWithoutProperties3 = _interopRequireDefault(_objectWithoutProperties2);
var _extends3 = require('babel-runtime/helpers/extends');
var _extends4 = _interopRequireDefault(_extends3);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
var _inherits2 = require('babel-runtime/helpers/inherits');
var _inherits3 = _interopRequireDefault(_inherits2);
exports.default = ShellBase;
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _classnames12 = require('classnames');
var _classnames13 = _interopRequireDefault(_classnames12);
var _propTypes = require('prop-types');
var _propTypes2 = _interopRequireDefault(_propTypes);
var _reactLifecyclesCompat = require('react-lifecycles-compat');
var _configProvider = require('../config-provider');
var _configProvider2 = _interopRequireDefault(_configProvider);
var _affix = require('../affix');
var _affix2 = _interopRequireDefault(_affix);
var _icon = require('../icon');
var _icon2 = _interopRequireDefault(_icon);
var _util = require('../util');
var _util2 = require('./util');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Shell
*/
function ShellBase(props) {
var _class, _temp, _initialiseProps;
var componentName = props.componentName;
var Shell = (_temp = _class = function (_Component) {
(0, _inherits3.default)(Shell, _Component);
function Shell(props) {
(0, _classCallCheck3.default)(this, Shell);
var _this = (0, _possibleConstructorReturn3.default)(this, _Component.call(this, props));
_initialiseProps.call(_this);
var deviceMap = (0, _util2.getCollapseMap)(props.device);
_this.layout = {};
_this.state = {
controll: false,
collapseMap: deviceMap,
device: props.device
};
return _this;
}
Shell.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps, prevState) {
var device = prevState.device;
if (nextProps.device !== device) {
var deviceMap = (0, _util2.getCollapseMap)(nextProps.device);
return {
controll: false,
collapseMap: deviceMap,
device: nextProps.device
};
}
return {};
};
Shell.prototype.componentDidMount = function componentDidMount() {
this.checkAsideFixed();
};
Shell.prototype.componentDidUpdate = function componentDidUpdate(prevProps) {
var _this2 = this;
if (prevProps.device !== this.props.device) {
var deviceMapBefore = (0, _util2.getCollapseMap)(prevProps.device);
var deviceMapAfter = (0, _util2.getCollapseMap)(this.props.device);
Object.keys(deviceMapAfter).forEach(function (block) {
var _ref = _this2.layout[block] || {},
props = _ref.props;
if (deviceMapBefore[block] !== deviceMapAfter[block]) {
if (props && typeof props.onCollapseChange === 'function') {
props.onCollapseChange(deviceMapAfter[block]);
}
}
});
}
setTimeout(function () {
// 如果左侧边栏固定
_this2.checkAsideFixed();
}, 201);
};
Shell.prototype.render = function render() {
return this.renderShell(this.props);
};
return Shell;
}(_react.Component), _class.displayName = componentName, _class._typeMark = componentName, _class.propTypes = (0, _extends4.default)({}, _configProvider2.default.propTypes, {
prefix: _propTypes2.default.string,
/**
* 设备类型
* @enumdesc 手机, 平板, PC电脑
*/
device: _propTypes2.default.oneOf(['phone', 'tablet', 'desktop']),
/**
* 设备类型
* @enumdesc 浅色, 深色, 主题色
*/
type: _propTypes2.default.oneOf(['light', 'dark', 'brand']),
/**
* 是否固定 header, 用sticky实现,IE下降级为Affix
*/
fixedHeader: _propTypes2.default.bool
}), _class.defaultProps = {
prefix: 'next-',
device: 'desktop',
type: 'light',
fixedHeader: false
}, _initialiseProps = function _initialiseProps() {
var _this3 = this;
this.checkAsideFixed = function () {
var fixedHeader = _this3.props.fixedHeader;
if (!fixedHeader) {
return;
}
var headerHeight = void 0;
if (_this3.headerRef && (_this3.navigationFixed || _this3.toolDockFixed)) {
headerHeight = _util.dom.getStyle(_this3.headerRef, 'height');
}
if (_this3.navigationFixed) {
var style = {};
style.marginLeft = _util.dom.getStyle(_this3.navRef, 'width');
_util.dom.addClass(_this3.navRef, 'fixed');
headerHeight && _util.dom.setStyle(_this3.navRef, { top: headerHeight });
_util.dom.setStyle(_this3.localNavRef || _this3.submainRef, style);
}
if (_this3.toolDockFixed) {
var _style = {};
_style.marginRight = _util.dom.getStyle(_this3.toolDockRef, 'width');
_util.dom.addClass(_this3.toolDockRef, 'fixed');
headerHeight && _util.dom.setStyle(_this3.toolDockRef, { top: headerHeight });
_util.dom.setStyle(_this3.localNavRef || _this3.submainRef, _style);
}
};
this.setChildCollapse = function (child, mark) {
var _state = _this3.state,
device = _state.device,
collapseMap = _state.collapseMap,
controll = _state.controll;
var collapse = child.props.collapse;
var deviceMap = (0, _util2.getCollapseMap)(device);
var props = {};
// 非受控模式
if ((0, _util2.isBoolean)(collapse) === false) {
props.collapse = controll ? collapseMap[mark] : deviceMap[mark];
// props.collapse = collapseMap[mark];
}
if (device !== 'phone' && mark === 'Navigation') {
props.miniable = true;
}
return _react2.default.cloneElement(child, props);
};
this.toggleAside = function (mark, props, e) {
var _extends2;
var _state2 = _this3.state,
device = _state2.device,
collapseMap = _state2.collapseMap;
var deviceMap = (0, _util2.getCollapseMap)(device);
var current = props.collapse;
var newCollapseMap = (0, _extends4.default)({}, deviceMap, collapseMap, (_extends2 = {}, _extends2[mark] = !current, _extends2));
_this3.setState({
controll: true,
collapseMap: newCollapseMap
});
if (props && typeof props.onCollapseChange === 'function') {
props.onCollapseChange(newCollapseMap[mark]);
}
var children = _this3.props.children;
var com = void 0;
if (mark === 'Navigation') {
com = children.filter(function (child) {
return child && child.type._typeMark.replace('Shell_', '') === mark && child.props.direction !== 'hoz';
}).pop();
} else {
com = children.filter(function (child) {
return child && child.type._typeMark.replace('Shell_', '') === mark;
}).pop();
}
var _com$props$triggerPro = com.props.triggerProps,
triggerProps = _com$props$triggerPro === undefined ? {} : _com$props$triggerPro;
if (typeof triggerProps.onClick === 'function') {
triggerProps.onClick(e, _this3.state.collapseMap[mark]);
}
};
this.toggleNavigation = function (e) {
var mark = 'Navigation';
var props = _this3.layout[mark].props;
if ('keyCode' in e && e.keyCode !== _util.KEYCODE.ENTER) {
return;
}
_this3.toggleAside(mark, props, e);
};
this.toggleLocalNavigation = function (e) {
var mark = 'LocalNavigation';
var props = _this3.layout[mark].props;
if ('keyCode' in e && e.keyCode !== _util.KEYCODE.ENTER) {
return;
}
_this3.toggleAside(mark, props, e);
};
this.toggleAncillary = function (e) {
var mark = 'Ancillary';
var props = _this3.layout[mark].props;
if ('keyCode' in e && e.keyCode !== _util.KEYCODE.ENTER) {
return;
}
_this3.toggleAside(mark, props, e);
};
this.toggleToolDock = function (e) {
var mark = 'ToolDock';
var props = _this3.layout[mark].props;
if ('keyCode' in e && e.keyCode !== _util.KEYCODE.ENTER) {
return;
}
_this3.toggleAside(mark, props, e);
};
this.saveHeaderRef = function (ref) {
_this3.headerRef = ref;
};
this.saveLocalNavRef = function (ref) {
_this3.localNavRef = ref;
};
this.saveNavRef = function (ref) {
_this3.navRef = ref;
};
this.saveSubmainRef = function (ref) {
_this3.submainRef = ref;
};
this.saveToolDockRef = function (ref) {
_this3.toolDockRef = ref;
};
this.renderShell = function (props) {
var _classnames, _classnames2, _classnames3, _classnames4, _classnames5, _classnames6, _classnames7, _classnames11;
var prefix = props.prefix,
children = props.children,
className = props.className,
type = props.type,
fixedHeader = props.fixedHeader,
others = (0, _objectWithoutProperties3.default)(props, ['prefix', 'children', 'className', 'type', 'fixedHeader']);
var device = _this3.state.device;
var layout = {};
layout.header = {};
var hasToolDock = false,
needNavigationTrigger = false,
needDockTrigger = false;
_react2.default.Children.map(children, function (child) {
if (child && typeof child.type === 'function') {
var mark = child.type._typeMark.replace('Shell_', '');
switch (mark) {
case 'Branding':
case 'Action':
layout.header[mark] = child;
break;
case 'MultiTask':
layout.taskHeader = child;
break;
case 'LocalNavigation':
if (!layout[mark]) {
layout[mark] = [];
}
layout[mark] = _this3.setChildCollapse(child, mark);
break;
case 'Ancillary':
if (!layout[mark]) {
layout[mark] = [];
}
layout[mark] = _this3.setChildCollapse(child, mark);
break;
case 'ToolDock':
hasToolDock = true;
if (!layout[mark]) {
layout[mark] = [];
}
_this3.toolDockFixed = child.props.fixed;
var childT = _this3.setChildCollapse(child, mark);
layout[mark] = childT;
break;
case 'AppBar':
case 'Content':
case 'Footer':
layout.content || (layout.content = []);
layout.content.push(child);
break;
case 'Page':
layout.page || (layout.page = []);
layout.page = child;
break;
case 'Navigation':
if (child.props.direction === 'hoz') {
layout.header[mark] = child;
} else {
if (!layout[mark]) {
layout[mark] = [];
}
needNavigationTrigger = true;
_this3.navigationFixed = child.props.fixed;
var childN = _this3.setChildCollapse(child, mark);
layout[mark] = childN;
}
break;
default:
break;
}
}
});
var headerCls = (0, _classnames13.default)((_classnames = {}, _classnames[prefix + 'shell-header'] = true, _classnames[prefix + 'shell-fixed-header'] = fixedHeader, _classnames));
var mainCls = (0, _classnames13.default)((_classnames2 = {}, _classnames2[prefix + 'shell-main'] = true, _classnames2));
var pageCls = (0, _classnames13.default)((_classnames3 = {}, _classnames3[prefix + 'shell-page'] = true, _classnames3));
var submainCls = (0, _classnames13.default)((_classnames4 = {}, _classnames4[prefix + 'shell-sub-main'] = true, _classnames4));
var asideCls = (0, _classnames13.default)((_classnames5 = {}, _classnames5[prefix + 'shell-aside'] = true, _classnames5));
var toolDockCls = (0, _classnames13.default)((_classnames6 = {}, _classnames6[prefix + 'aside-tooldock'] = true, _classnames6));
var navigationCls = (0, _classnames13.default)((_classnames7 = {}, _classnames7[prefix + 'aside-navigation'] = true, _classnames7[prefix + 'shell-collapse'] = layout.Navigation && layout.Navigation.props.collapse, _classnames7));
if (hasToolDock) {
if (device === 'phone') {
needDockTrigger = true;
}
}
// 如果存在垂直模式的 Navigation, 则需要在 Branding 上出现 trigger
if (needNavigationTrigger) {
var branding = layout.header.Branding;
var _layout$Navigation$pr = layout.Navigation.props,
trigger = _layout$Navigation$pr.trigger,
collapse = _layout$Navigation$pr.collapse;
if ('trigger' in layout.Navigation.props) {
trigger = trigger && _react2.default.cloneElement(trigger, {
onClick: _this3.toggleNavigation,
'aria-expanded': !collapse
}) || trigger;
} else {
trigger = _react2.default.createElement(
'div',
{
key: 'nav-trigger',
role: 'button',
tabIndex: 0,
'aria-expanded': !collapse,
'aria-label': 'toggle',
className: 'nav-trigger',
onClick: _this3.toggleNavigation,
onKeyDown: _this3.toggleNavigation
},
collapse ? _react2.default.createElement(_icon2.default, { size: 'small', type: 'toggle-right' }) : _react2.default.createElement(_icon2.default, { size: 'small', type: 'toggle-left' })
);
}
if (!branding) {
trigger && (layout.header.Branding = trigger);
} else {
layout.header.Branding = _react2.default.cloneElement(branding, {}, [trigger, branding.props.children]);
}
}
// 如果存在 toolDock, 则需要在 Action 上出现 trigger
if (needDockTrigger) {
var action = layout.header.Action;
var _layout$ToolDock$prop = layout.ToolDock.props,
_trigger = _layout$ToolDock$prop.trigger,
_collapse = _layout$ToolDock$prop.collapse;
if ('trigger' in layout.ToolDock.props) {
_trigger = _trigger && _react2.default.cloneElement(_trigger, {
onClick: _this3.toggleToolDock,
'aria-expanded': !_collapse
}) || _trigger;
} else {
_trigger = _react2.default.createElement(
'div',
{
key: 'dock-trigger',
tabIndex: 0,
role: 'button',
'aria-expanded': !_collapse,
'aria-label': 'toggle',
className: 'dock-trigger',
onClick: _this3.toggleToolDock,
onKeyDown: _this3.toggleToolDock
},
_react2.default.createElement(_icon2.default, { size: 'small', type: 'add' })
);
}
if (!action) {
layout.header.Action = _trigger;
} else {
layout.header.Action = _react2.default.cloneElement(action, {}, [action.props.children, _trigger]);
}
}
var headerDom = [],
contentArr = [],
innerArr = [],
taskHeaderDom = null;
if (layout.taskHeader) {
var _classnames8;
var taskHeaderCls = (0, _classnames13.default)((_classnames8 = {}, _classnames8[prefix + 'shell-task-header'] = true, _classnames8));
taskHeaderDom = _react2.default.createElement(
'section',
{ key: 'task-header', className: taskHeaderCls },
layout.taskHeader
);
}
// 按照dom结构,innerArr 包括 LocalNavigation content Ancillary
if (layout.LocalNavigation) {
var _classnames9;
var _layout$LocalNavigati = layout.LocalNavigation.props,
_trigger2 = _layout$LocalNavigati.trigger,
_collapse2 = _layout$LocalNavigati.collapse;
if ('trigger' in layout.LocalNavigation.props) {
_trigger2 = _trigger2 && _react2.default.cloneElement(_trigger2, {
onClick: _this3.toggleLocalNavigation,
'aria-expanded': !_collapse2
}) || _trigger2;
} else {
_trigger2 = _react2.default.createElement(
'div',
{
key: 'local-nav-trigger',
role: 'button',
tabIndex: 0,
'aria-expanded': !_collapse2,
'aria-label': 'toggle',
className: 'local-nav-trigger aside-trigger',
onClick: _this3.toggleLocalNavigation,
onKeyDown: _this3.toggleLocalNavigation
},
_collapse2 ? _react2.default.createElement(_icon2.default, { size: 'small', type: 'arrow-right' }) : _react2.default.createElement(_icon2.default, { size: 'small', type: 'arrow-left' })
);
}
var localNavCls = (0, _classnames13.default)(asideCls, (_classnames9 = {}, _classnames9[prefix + 'aside-localnavigation'] = true, _classnames9));
innerArr.push(_react2.default.createElement(
'aside',
{ key: 'localnavigation', className: localNavCls, ref: _this3.saveLocalNavRef },
_react2.default.cloneElement(layout.LocalNavigation, {}, [_react2.default.createElement(
'div',
{ key: 'wrapper', className: prefix + 'shell-content-wrapper' },
layout.LocalNavigation.props.children
), _trigger2])
));
}
if (layout.content) {
innerArr.push(_react2.default.createElement(
'section',
{ key: 'submain', className: submainCls, ref: _this3.saveSubmainRef },
layout.content
));
}
if (layout.Ancillary) {
var _classnames10;
var _layout$Ancillary$pro = layout.Ancillary.props,
_trigger3 = _layout$Ancillary$pro.trigger,
_collapse3 = _layout$Ancillary$pro.collapse;
if ('trigger' in layout.Ancillary.props) {
_trigger3 = _trigger3 && _react2.default.cloneElement(_trigger3, {
onClick: _this3.toggleAncillary,
'aria-expanded': !_collapse3
}) || _trigger3;
} else {
_trigger3 = _react2.default.createElement(
'div',
{
key: 'ancillary-trigger',
role: 'button',
tabIndex: 0,
'aria-expanded': !_collapse3,
'aria-label': 'toggle',
className: 'ancillary-trigger aside-trigger',
onClick: _this3.toggleAncillary,
onKeyDown: _this3.toggleAncillary
},
_collapse3 ? _react2.default.createElement(_icon2.default, { size: 'small', type: 'arrow-left' }) : _react2.default.createElement(_icon2.default, { size: 'small', type: 'arrow-right' })
);
}
var ancillaryCls = (0, _classnames13.default)(asideCls, (_classnames10 = {}, _classnames10[prefix + 'aside-ancillary'] = true, _classnames10));
innerArr.push(_react2.default.createElement(
'aside',
{ key: 'ancillary', className: ancillaryCls },
_react2.default.cloneElement(layout.Ancillary, {}, [_react2.default.createElement(
'div',
{ key: 'wrapper', className: prefix + 'shell-content-wrapper' },
layout.Ancillary.props.children
), _trigger3])
));
}
// 按照dom结构, arr 包括 header Navigation ToolDock 和 innerArr
if (Object.keys(layout.header).length > 0) {
var _dom = _react2.default.createElement(
'header',
{ key: 'header', className: headerCls, ref: _this3.saveHeaderRef },
layout.header.Branding,
layout.header.Navigation,
layout.header.Action
);
if (fixedHeader && _util.env.ieVersion) {
headerDom = _react2.default.createElement(
_affix2.default,
{ style: { zIndex: 9 } },
_dom
);
} else {
headerDom = _dom;
}
}
layout.Navigation && contentArr.push(_react2.default.createElement(
'aside',
{ key: 'navigation', className: navigationCls, ref: _this3.saveNavRef },
_react2.default.cloneElement(layout.Navigation, {
className: (0, _classnames13.default)(asideCls, layout.Navigation.props.className)
})
));
// const contentArea = innerArr.length > 0
// ? <section key="main" className={mainCls}>{innerArr}</section>
// : layout.page;
// contentArr.push(contentArea);
contentArr = contentArr.concat(innerArr.length > 0 ? innerArr : [_react2.default.createElement(
'section',
{ key: 'page', ref: _this3.saveSubmainRef, className: submainCls },
layout.page
)]);
layout.ToolDock && contentArr.push(_react2.default.createElement(
'aside',
{ key: 'tooldock', className: toolDockCls, ref: _this3.saveToolDockRef },
_react2.default.cloneElement(layout.ToolDock, {
className: (0, _classnames13.default)(asideCls, layout.ToolDock.props.className),
key: 'tooldock'
})
));
var cls = (0, _classnames13.default)((_classnames11 = {}, _classnames11[prefix + 'shell'] = true, _classnames11[prefix + 'shell-' + device] = true, _classnames11[prefix + 'shell-' + type] = true, _classnames11[className] = !!className, _classnames11));
if (componentName === 'Page') {
return _react2.default.createElement(
'section',
{ className: pageCls },
children
);
}
_this3.layout = layout;
return _react2.default.createElement(
'section',
(0, _extends4.default)({ className: cls }, others),
headerDom,
taskHeaderDom,
_react2.default.createElement(
'section',
{ className: mainCls },
contentArr
)
);
};
}, _temp);
Shell.displayName = 'Shell';
return (0, _reactLifecyclesCompat.polyfill)(Shell);
}
module.exports = exports['default'];