chowa
Version:
UI component library based on React
146 lines (145 loc) • 5.5 kB
JavaScript
/**
* @license chowa v1.1.3
*
* Copyright (c) Chowa Techonlogies Co.,Ltd.(http://www.chowa.cn).
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
;
Object.defineProperty(exports, "__esModule", { value: true });
const React = require("react");
const utils_1 = require("../utils");
const menu_item_1 = require("./menu-item");
const menu_group_1 = require("./menu-group");
const menu_submenu_1 = require("./menu-submenu");
const icon_1 = require("../icon");
exports.tierSpace = 22;
function computedIconAndText(children) {
let icon = null;
let text = null;
const hasWrapper = React.Children.count(children) === 1
&& children.props
&& React.Children.count(children.props.children) > 0;
const viewChildren = hasWrapper ? children.props.children : children;
React.Children.map(viewChildren, (child) => {
if (!icon && utils_1.isReactElement(child) && child.type === icon_1.default) {
icon = child;
}
else if (!text && ((utils_1.isReactElement(child) && child.type !== icon_1.default) || utils_1.isExist(child))) {
text = child;
}
});
return { icon, text, hasWrapper };
}
exports.computedIconAndText = computedIconAndText;
function transformReactNodeToData(children, tier = 1, inSubmenu = false, parentKey = 'root') {
const data = [];
const curTier = inSubmenu ? tier + 1 : tier;
React.Children.forEach(children, (child, key) => {
if (!utils_1.isReactElement(child)) {
return;
}
const content = child.props.children;
const attributes = utils_1.omitProps(child.props, ['children']);
switch (child.type) {
case menu_item_1.default:
data.push(Object.assign(Object.assign({}, attributes), { tier: curTier, type: 'item', content, extras: computedIconAndText(content) }));
break;
case menu_group_1.default:
data.push(Object.assign(Object.assign({}, attributes), { tier: curTier, type: 'group', data: transformReactNodeToData(content, curTier, false, `${parentKey}-${key}`) }));
break;
case menu_submenu_1.default:
data.push(Object.assign(Object.assign({}, attributes), { tier: curTier, type: 'submenu', extras: computedIconAndText(attributes.title), inSubmenu,
parentKey, collapseKey: key, data: transformReactNodeToData(content, curTier, true, `${parentKey}-${key}`) }));
break;
}
});
return data;
}
exports.transformReactNodeToData = transformReactNodeToData;
function hasActiveRecord(data, activeIndex) {
return !data.every((record) => {
if (record.type === 'item' && record.index === activeIndex) {
return false;
}
if (record.type !== 'item' && record.data.length > 0) {
return !hasActiveRecord(record.data, activeIndex);
}
return true;
});
}
exports.hasActiveRecord = hasActiveRecord;
function collectCollapse(data, activeIndex) {
let manager = {};
const appendToManager = (parentKey, collapseKey) => {
if (!utils_1.hasProperty(manager, parentKey)) {
manager[parentKey] = [];
}
manager[parentKey].push(collapseKey);
};
data.forEach((record) => {
if (record.type === 'item') {
return;
}
const hasActiveIndex = utils_1.isExist(activeIndex) && hasActiveRecord(record.data, activeIndex);
if (record.type === 'submenu' && (record.open || hasActiveIndex)) {
appendToManager(record.parentKey, record.collapseKey);
}
if (record.data.length > 0) {
manager = Object.assign(Object.assign({}, manager), collectCollapse(record.data, activeIndex));
}
});
return manager;
}
function initCollapseManager(data, accordion, activeIndex) {
const manager = collectCollapse(data, activeIndex);
if (accordion) {
for (const parentKey in manager) {
if (manager[parentKey].length > 1) {
manager[parentKey] = [manager[parentKey].pop()];
}
}
}
return manager;
}
exports.initCollapseManager = initCollapseManager;
function isActiveCollpase(manager, parentKey, collapseKey) {
return utils_1.hasProperty(manager, parentKey) && manager[parentKey].includes(collapseKey);
}
exports.isActiveCollpase = isActiveCollpase;
function cloneManager(manager) {
const ret = {};
for (const parentKey in manager) {
ret[parentKey] = [].concat(manager[parentKey]);
}
return ret;
}
exports.cloneManager = cloneManager;
function increaseTier(data) {
return data.map((record) => {
record.tier += 1;
if (record.type === 'submenu') {
record.inSubmenu = true;
}
if (record.type !== 'item') {
record.data = increaseTier(record.data);
}
return record;
});
}
function mergeOuterItemToSubmenu(data, index) {
const ret = [].concat(data);
const merges = increaseTier(ret.splice(index));
const title = React.createElement(icon_1.default, { type: 'omit', style: { margin: 0 } });
ret.push({
type: 'submenu',
tier: 1,
title,
data: merges,
placement: 'left',
extras: computedIconAndText(title)
});
return ret;
}
exports.mergeOuterItemToSubmenu = mergeOuterItemToSubmenu;