eapp-amis-theme-editor
Version:
amis主题编辑器
587 lines (583 loc) • 20.6 kB
JavaScript
/**
* amis-theme-editor v2.0.11-beta.2
* Copyright 2018-2023 @fex
*/
import { __assign } from 'tslib';
import { Button, Icon } from 'amis-ui';
import cloneDeep from 'lodash/cloneDeep';
import React__default from 'react';
import { ColorGenerator } from 'amis-theme-editor-helper';
import '../icons/index.js';
import cx from 'classnames';
import { uuid, render } from 'amis-core';
import findIndex from 'lodash/findIndex';
import { i18n } from 'i18n-runtime';
import { SketchPicker } from 'react-color';
import { getSchemaTpl } from '../tpl.js';
import { Icon as Icon$1 } from 'amis';
function setColor(body, colors, prefix) {
body.colors = colors.map(function (item, i) {
return {
token: prefix + (i + 1),
label: "".concat(i + 1, "-").concat(item.hex),
color: item.hex,
index: i
};
});
}
function setAllColor(value, data) {
var _a;
var tempData = cloneDeep(data);
var colorGenerator = new ColorGenerator(value);
var derivedColors = colorGenerator.getDerivedColor();
var functionColors = colorGenerator.getFunctionalColor();
var neutralColors = colorGenerator.getNeutralColor();
var colors = colorGenerator.getDataColor();
setColor(tempData.global.colors.brand.body, derivedColors, tempData.global.colors.brand.token);
//中性色
tempData.global.colors.neutral.body.forEach(function (color) {
color.body.colors = neutralColors.map(function (item, i) {
var token = color.token;
return {
token: token + (i + 1),
label: "".concat(i, "-").concat(item.hex),
color: item.hex,
index: i
};
});
});
functionColors.forEach(function (color, i) {
tempData.global.colors.func.body[i].body.main = color.hex;
var funcColorGenerator = new ColorGenerator(color.hex);
var colors = funcColorGenerator.getDerivedColor();
setColor(tempData.global.colors.func.body[i].body, colors, tempData.global.colors.func.body[i].token);
});
// 数据色
(_a = tempData.global.colors.data) === null || _a === void 0 ? void 0 : _a.body.forEach(function (item, i) {
if (i < 3) {
item.colors = colors[i].map(function (n) {
return {
value: n.checkedColor
};
});
}
});
return tempData;
}
// 根据主色生成色阶按钮
function CreateColorButton(props) {
var changeAll = false;
var ConfigButton = render({
type: 'button',
level: 'link',
label: i18n("e366ccf1556c0672dcecba135ed5472e"),
size: 'xs',
tooltip: i18n("c91314c81f9f6c7edc0476b6f1c169db"),
tooltipPlacement: 'top',
actionType: 'dialog',
dialog: {
className: 'theme-color-config-dialog',
title: [{
type: 'icon',
icon: 'status-warning',
className: 'icon title-color'
}, i18n("bbed50fd3a066f9974441671d541b212")],
body: i18n("67179ff9e68ecae99931d84d42eb9316"),
actions: [{
type: 'checkbox',
name: 'checkbox',
visible: !!props.isBrand,
className: 'brand-color-check',
option: i18n("5b72549d59ffd2803c3a2e58228ece0c"),
onChange: function (value) {
changeAll = value;
}
}, {
type: 'button',
actionType: 'cancel',
label: i18n("625fb26b4b3340f7872b411f401e754c")
}, {
type: 'button',
actionType: 'confirm',
label: i18n("e83a256e4f5bb4ff8b3d804b5473217a"),
primary: true,
onClick: function () {
var tempData = cloneDeep(props.data);
var pathTemp = props.path.split('.');
var children = tempData[pathTemp[0]];
for (var i = 1; i < pathTemp.length; i++) {
children = children[pathTemp[i]];
}
var mainColor = children.body.colors[4].color;
children.body.main = mainColor;
var funcColorGenerator = new ColorGenerator(mainColor);
var colors = funcColorGenerator.getDerivedColor();
setColor(children.body, colors, children.token);
if (changeAll && props.isBrand) {
tempData = setAllColor(mainColor, tempData);
}
props.onChange(tempData);
// 关闭右侧抽屉,避免数据混乱
props.handleCloseRightPanel();
}
}]
}
});
return ConfigButton;
}
function ColorPicker(_a) {
var defaultColor = _a.defaultColor,
onColorChange = _a.onColorChange;
var _b = React__default.useState(defaultColor || '#2468f2'),
color = _b[0],
setColor = _b[1];
React__default.useEffect(function () {
setColor(defaultColor || '#2468f2');
}, [defaultColor]);
return React__default.createElement(SketchPicker, {
width: "230px",
disableAlpha: true,
color: color,
onChangeComplete: function (value) {
setColor(value.hex);
onColorChange && onColorChange(value.hex);
}
});
}
var ColorPanel = function (props) {
var colors = props.colors,
token = props.token,
activeToken = props.activeToken,
activeId = props.activeId,
onEdit = props.onEdit,
title = props.title,
path = props.path,
data = props.data,
onChange = props.onChange;
var common = colors.common;
var commonColorMap = common.map(function (item) {
return item.color;
});
var colorMap = colors.colors;
var leftColorMap = colors.colors.filter(function (item, i) {
return commonColorMap.indexOf(i) === -1;
});
var isActive = token === activeToken;
var isNeutral = token.indexOf('--colors-neutral-') > -1;
var isNeutralText = token === '--colors-neutral-text-';
// 编辑常用颜色
function handleColorPicker(index, isCheck, isSystem) {
if (!isCheck && isSystem) {
// 文字前5个固定,其余前4个固定
return;
}
var pathTemp = path.split('.');
var colors = data[pathTemp[0]];
for (var i = 1; i < pathTemp.length; i++) {
colors = colors[pathTemp[i]];
}
if (isCheck) {
colors.common.push({
id: leftColorMap[index].index + 1,
label: leftColorMap[index].label,
color: leftColorMap[index].index
});
} else {
colors.common.splice(index, 1);
}
onChange && onChange(data);
}
// 修改颜色
function handleColorEdit(index, item, isSystem) {
// 中性色颜色路径特殊处理
var isBrandMain = path === 'global.colors.brand.body' && item.color === 4;
var changeAll = isBrandMain ? data.global.colors.brand.body.common[0].changeAll : false;
// TODO: themeData暂时在存一份解决问题,需要解决函数内数据不更新的问题
var themeData = data;
onEdit({
title: title,
path: "".concat(path, ".common.").concat(index),
body: getSchemaTpl('normal', [{
name: 'label',
type: 'input-text',
label: i18n("3649bbe5c9b1627ff779ef11058ce176"),
disabled: isSystem,
required: true
}, {
type: 'input-text',
disabled: true,
label: i18n("122afa60000b5367d28fe360cc1ab400"),
required: true,
value: colorMap[item.color].token
}, {
asFormItem: true,
required: true,
label: i18n("ce0aa1714cde2342fa6583664845fc94"),
mode: 'normal',
defaultColor: colorMap[item.color].color,
component: ColorPicker,
onColorChange: function (value) {
var pathTemp = path.split('.');
var colors = themeData[pathTemp[0]];
for (var i = 1; i < pathTemp.length; i++) {
colors = colors[pathTemp[i]];
}
colors.colors[item.color].color = value;
if (changeAll && isBrandMain) {
themeData = setAllColor(value, themeData);
}
onChange && onChange(themeData);
}
}, {
type: 'fieldSet',
title: i18n("6e196ba10b126b5c96ae29984967efa2"),
visible: isBrandMain,
body: [{
name: 'changeAll',
type: 'switch',
label: i18n("5b72549d59ffd2803c3a2e58228ece0c"),
labelWidth: 200,
onChange: function (value) {
themeData.global.colors.brand.body.common[0].changeAll = value;
changeAll = value;
onChange && onChange(themeData);
}
}]
}])
});
}
return React__default.createElement("div", {
className: "ThemeEditor-color"
}, React__default.createElement("div", {
className: "ThemeEditor-color-common"
}, common.map(function (item, i) {
var token = colorMap[item.color].token.replace('--colors-', '');
var isSystem = i <= 3 || isNeutralText && i <= 4; // 系统给定,不可修改
return React__default.createElement("div", {
className: cx('ThemeEditor-color-common-item', activeId === "".concat(path, ".common.").concat(i) && 'ThemeEditor-color-common-active', isActive && isSystem && 'ThemeEditor-color-common-system'),
key: item.id || i,
onClick: function () {
isActive ? handleColorPicker(i, false, isSystem) : handleColorEdit(i, item, isSystem);
}
}, React__default.createElement("div", {
className: "ThemeEditor-color-common-bg",
style: {
background: colorMap[item.color].color || 'fff',
color: ColorGenerator.getFontColor(colorMap[item.color].color || '')
}
}, colorMap[item.color].color, i === 0 && !isNeutral && React__default.createElement("span", {
className: "ThemeEditor-color-common-base"
}, i18n("549c3eb3ef1d8c0142c27ac6fa6e5e57"))), React__default.createElement("div", {
className: "ThemeEditor-color-common-description"
}, React__default.createElement("div", {
className: "ThemeEditor-color-common-token"
}, token), React__default.createElement("div", {
className: "ThemeEditor-color-common-label"
}, i18n(item.label)), isActive && React__default.createElement(Icon$1, {
icon: "checkbox-check",
className: "ThemeEditor-color-common-check"
})));
}), isActive && leftColorMap.map(function (item, i) {
var token = item.token.replace('--colors-', '');
return React__default.createElement("div", {
className: "ThemeEditor-color-common-item",
key: item.token || i,
onClick: function () {
handleColorPicker(i, true, false);
}
}, React__default.createElement("div", {
className: "ThemeEditor-color-common-bg",
style: {
background: item.color || 'fff',
color: ColorGenerator.getFontColor(item.color || '')
}
}, item.color), React__default.createElement("div", {
className: "ThemeEditor-color-common-description"
}, React__default.createElement("div", {
className: "ThemeEditor-color-common-token"
}, token), React__default.createElement("div", {
className: "ThemeEditor-color-common-label"
}, item.label), React__default.createElement(Icon$1, {
icon: "checkbox",
className: "ThemeEditor-color-common-check"
})));
})));
};
var BrandColorPanel = function (props) {
var data = props.data,
onChange = props.onChange;
var colors = props.data.global.colors;
var brand = colors.brand;
return React__default.createElement(ColorPanel, {
colors: brand.body,
token: brand.token,
activeToken: props.activeToken,
activeId: props.activeId,
onEdit: props.onEdit,
title: i18n("92544546c88558b7ecda8ce79b579803"),
path: "global.colors.brand.body",
data: data,
onChange: onChange
});
};
var NeutralColorPanel = function (props) {
var data = props.data,
onChange = props.onChange,
handleSetActiveToken = props.handleSetActiveToken,
activeToken = props.activeToken,
activeId = props.activeId,
onEdit = props.onEdit;
var neutral = props.data.global.colors.neutral.body;
return React__default.createElement(React__default.Fragment, null, neutral.map(function (item, index) {
return React__default.createElement("div", {
className: "ThemeEditor-body-content-item ThemeEditor-body-content-item--sub",
key: item.token
}, React__default.createElement("div", {
className: "ThemeEditor-body-content-item-title ThemeEditor-body-content-item-title--sub"
}, i18n(item.label), React__default.createElement(Button, {
level: "link",
size: "xs",
onClick: function () {
handleSetActiveToken(item.token);
}
}, activeToken === item.token ? i18n("769d88e425e03120b83ee4ed6b9d588e") : i18n("95b351c86267f3aedf89520959bce689"))), React__default.createElement(ColorPanel, {
colors: item.body,
token: item.token,
activeId: activeId,
activeToken: activeToken,
onEdit: onEdit,
title: "\u7F16\u8F91".concat(item.label),
path: "global.colors.neutral.body.".concat(index, ".body"),
data: data,
onChange: onChange
}));
}));
};
var FuncColorPanel = function (props) {
var colorTypes = props.colorTypes,
data = props.data,
onChange = props.onChange,
onEdit = props.onEdit,
activeToken = props.activeToken,
activeId = props.activeId,
handleSetActiveToken = props.handleSetActiveToken,
handleCloseRightPanel = props.handleCloseRightPanel;
var otherIndex = findIndex(colorTypes, function (item) {
return item.token === '--colors-other-';
});
var _a = React__default.useState(otherIndex),
hiddenIndex = _a[0],
setHiddenIndex = _a[1];
return React__default.createElement(React__default.Fragment, null, colorTypes.map(function (item, index) {
var isHidden = hiddenIndex === index;
var isActive = item.token === activeToken;
return React__default.createElement("div", {
className: "ThemeEditor-body-content-item ThemeEditor-body-content-item--sub",
key: item.token
}, React__default.createElement("div", {
className: "ThemeEditor-body-content-item-title ThemeEditor-body-content-item-title--sub"
}, i18n(item.label), index === colorTypes.length - 1 && React__default.createElement(Icon, {
icon: "right-arrow",
className: cx('ThemeEditor-arrow-icon', isHidden && 'ThemeEditor-arrow-icon-reverse'),
onClick: function () {
!isActive && setHiddenIndex(isHidden ? -1 : index);
}
}), React__default.createElement(Button, {
level: "link",
size: "xs",
onClick: function () {
isHidden && setHiddenIndex(-1);
handleSetActiveToken(item.token);
}
}, activeToken === item.token ? i18n("769d88e425e03120b83ee4ed6b9d588e") : i18n("95b351c86267f3aedf89520959bce689")), React__default.createElement(CreateColorButton, {
data: data,
path: "global.colors.func.body.".concat(index),
onChange: onChange,
handleCloseRightPanel: handleCloseRightPanel
})), !isHidden && React__default.createElement(ColorPanel, {
colors: item.body,
token: item.token,
activeId: activeId,
activeToken: activeToken,
onEdit: onEdit,
title: "\u7F16\u8F91".concat(item.label),
path: "global.colors.func.body.".concat(index, ".body"),
data: data,
onChange: onChange
}));
}));
};
var DataColorPanel = function (props) {
var _a;
var data = props.data,
onEdit = props.onEdit,
activeId = props.activeId;
var dataColors = ((_a = data.global.colors.data) === null || _a === void 0 ? void 0 : _a.body) || [];
function editColor(index) {
onEdit({
title: i18n("11e9d79e5e4152d28b299d2bd53c4a0b"),
path: "global.colors.data.body.".concat(index),
body: getSchemaTpl('normal', [{
name: 'label',
type: 'input-text',
label: i18n("d7ec2d3fea4756bc1642e0f10c180cf5"),
required: true
}, {
name: 'colors',
type: 'combo',
label: i18n("6b36c6f7ec834692ec6c8e3816349fdd"),
required: true,
multiple: true,
items: [{
type: 'input-color',
name: 'value'
}]
}])
});
}
function handleDataColorDelete(index) {
var _a;
var tempData = cloneDeep(props.data);
(_a = tempData.global.colors.data) === null || _a === void 0 ? void 0 : _a.body.splice(index, 1);
props.onChange(tempData);
}
return React__default.createElement(React__default.Fragment, null, dataColors.map(function (item, index) {
return React__default.createElement("div", {
className: "ThemeEditor-color-data",
key: index
}, React__default.createElement("div", {
className: "ThemeEditor-color-data-title"
}, item.label, item.custom ? React__default.createElement(Button, {
className: "theme-icon",
level: "link",
onClick: function () {
return handleDataColorDelete(index);
}
}, React__default.createElement(Icon, {
icon: "delete-button",
className: "theme-icon-svg theme-delete-icon"
})) : null), React__default.createElement("div", {
className: cx('ThemeEditor-color-data-items', activeId === "global.colors.data.body.".concat(index) && 'ThemeEditor-color-data-items--active'),
onClick: function () {
return editColor(index);
}
}, item.colors.map(function (n, i) {
return React__default.createElement("div", {
className: "ThemeEditor-color-data-item",
style: {
background: n.value
},
key: i
}, n.value);
})));
}));
};
var ThemeColor = function (props) {
var data = props.data,
activeToken = props.activeToken,
handleSetActiveToken = props.handleSetActiveToken,
onChange = props.onChange,
handleCloseRightPanel = props.handleCloseRightPanel;
var _a = data.global.colors,
brand = _a.brand,
func = _a.func;
return {
title: i18n("6b36c6f7ec834692ec6c8e3816349fdd"),
body: [{
title: i18n("2b250fe214bc8b93fb78d795a47d7a6c"),
action: {
colorEditButton: {
type: 'button',
level: 'link',
label: activeToken === brand.token ? i18n("769d88e425e03120b83ee4ed6b9d588e") : i18n("95b351c86267f3aedf89520959bce689"),
size: 'xs',
onClick: function () {
handleSetActiveToken(brand.token);
}
},
configButton: React__default.createElement(CreateColorButton, {
data: data,
path: "global.colors.brand",
onChange: onChange,
isBrand: true,
handleCloseRightPanel: handleCloseRightPanel
})
},
body: function (onEdit) {
return React__default.createElement(BrandColorPanel, __assign({}, props, {
onEdit: onEdit
}));
}
}, {
title: i18n("af09bd51b66a26d8db3119e95b5d28fe"),
body: function (onEdit) {
return React__default.createElement(NeutralColorPanel, __assign({}, props, {
onEdit: onEdit
}));
}
}, {
title: i18n("b6c3e2dcf4053e5f24d15b63a29f5afd"),
body: function (onEdit) {
return React__default.createElement(FuncColorPanel, __assign({
colorTypes: func.body
}, props, {
onEdit: onEdit
}));
}
}, {
title: i18n("328215447d0e128a845729dab5ce9837"),
action: {
addButton: {
title: i18n("db31a89fcdba29c16f19d5c5bc7c82f2"),
body: {
type: 'form',
body: [{
name: 'label',
type: 'input-text',
label: i18n("d7ec2d3fea4756bc1642e0f10c180cf5"),
required: true
}, {
name: 'colors',
type: 'combo',
label: i18n("6b36c6f7ec834692ec6c8e3816349fdd"),
required: true,
multiple: true,
items: [{
type: 'input-color',
name: 'value'
}]
}],
onFinished: function (data) {
var label = data.label,
colors = data.colors;
var newDataColor = {
custom: true,
token: uuid(),
label: label,
colors: colors
};
var tempData = cloneDeep(props.data);
if (!tempData.global.colors.data) {
tempData.global.colors.data = {
label: i18n("328215447d0e128a845729dab5ce9837"),
body: []
};
}
tempData.global.colors.data.body.push(newDataColor);
props.onChange(tempData);
}
}
}
},
body: function (onEdit) {
return React__default.createElement(DataColorPanel, __assign({}, props, {
onEdit: onEdit
}));
}
}]
};
};
var Color = (function () {
return ThemeColor;
});
export { Color as default };